缓冲区与 TypedArray


Buffer 实例也是 JavaScript Uint8ArrayTypedArray 实例。 所有 TypedArray 方法都可在 Buffer 上使用。 但是,Buffer API 和 TypedArray API 之间存在细微的不兼容。

            Buffer instances are also JavaScript Uint8Array and TypedArray instances. All TypedArray methods are available on Buffers. There are, however, subtle incompatibilities between the Buffer API and the TypedArray API.

            In particular:

            There are two ways to create new TypedArray instances from a Buffer:

            • Passing a Buffer to a TypedArray constructor will copy the Buffers contents, interpreted as an array of integers, and not as a byte sequence of the target type.
            import { Buffer } from 'node:buffer';
            
            const buf = Buffer.from([1, 2, 3, 4]);
            const uint32array = new Uint32Array(buf);
            
            console.log(uint32array);
            
            // Prints: Uint32Array(4) [ 1, 2, 3, 4 ]const { Buffer } = require('node:buffer');
            
            const buf = Buffer.from([1, 2, 3, 4]);
            const uint32array = new Uint32Array(buf);
            
            console.log(uint32array);
            
            // Prints: Uint32Array(4) [ 1, 2, 3, 4 ]
            • Passing the Buffers underlying ArrayBuffer will create a TypedArray that shares its memory with the Buffer.
            import { Buffer } from 'node:buffer';
            
            const buf = Buffer.from('hello', 'utf16le');
            const uint16array = new Uint16Array(
              buf.buffer,
              buf.byteOffset,
              buf.length / Uint16Array.BYTES_PER_ELEMENT);
            
            console.log(uint16array);
            
            // Prints: Uint16Array(5) [ 104, 101, 108, 108, 111 ]const { Buffer } = require('node:buffer');
            
            const buf = Buffer.from('hello', 'utf16le');
            const uint16array = new Uint16Array(
              buf.buffer,
              buf.byteOffset,
              buf.length / Uint16Array.BYTES_PER_ELEMENT);
            
            console.log(uint16array);
            
            // Prints: Uint16Array(5) [ 104, 101, 108, 108, 111 ]

            It is possible to create a new Buffer that shares the same allocated memory as a TypedArray instance by using the TypedArray object's .buffer property in the same way. Buffer.from() behaves like new Uint8Array() in this context.

            import { Buffer } from 'node:buffer';
            
            const arr = new Uint16Array(2);
            
            arr[0] = 5000;
            arr[1] = 4000;
            
            // Copies the contents of `arr`.
            const buf1 = Buffer.from(arr);
            
            // Shares memory with `arr`.
            const buf2 = Buffer.from(arr.buffer);
            
            console.log(buf1);
            // Prints: <Buffer 88 a0>
            console.log(buf2);
            // Prints: <Buffer 88 13 a0 0f>
            
            arr[1] = 6000;
            
            console.log(buf1);
            // Prints: <Buffer 88 a0>
            console.log(buf2);
            // Prints: <Buffer 88 13 70 17>const { Buffer } = require('node:buffer');
            
            const arr = new Uint16Array(2);
            
            arr[0] = 5000;
            arr[1] = 4000;
            
            // Copies the contents of `arr`.
            const buf1 = Buffer.from(arr);
            
            // Shares memory with `arr`.
            const buf2 = Buffer.from(arr.buffer);
            
            console.log(buf1);
            // Prints: <Buffer 88 a0>
            console.log(buf2);
            // Prints: <Buffer 88 13 a0 0f>
            
            arr[1] = 6000;
            
            console.log(buf1);
            // Prints: <Buffer 88 a0>
            console.log(buf2);
            // Prints: <Buffer 88 13 70 17>

            When creating a Buffer using a TypedArray's .buffer, it is possible to use only a portion of the underlying ArrayBuffer by passing in byteOffset and length parameters.

            import { Buffer } from 'node:buffer';
            
            const arr = new Uint16Array(20);
            const buf = Buffer.from(arr.buffer, 0, 16);
            
            console.log(buf.length);
            // Prints: 16const { Buffer } = require('node:buffer');
            
            const arr = new Uint16Array(20);
            const buf = Buffer.from(arr.buffer, 0, 16);
            
            console.log(buf.length);
            // Prints: 16

            The Buffer.from() and TypedArray.from() have different signatures and implementations. Specifically, the TypedArray variants accept a second argument that is a mapping function that is invoked on every element of the typed array:

            • TypedArray.from(source[, mapFn[, thisArg]])

            The Buffer.from() method, however, does not support the use of a mapping function: