We know that computers store and represent data in the form of binaries i.e sets of 0s and 1s. NodeJS provides the Buffer module with the Buffer class to handle binary data. Each binary digit represents a binary bit and 8 adjacent bit represents a byte. Buffer objects in NodeJS allow the representation of a fixed-length sequence of bytes.
The Buffer class is a global type derived from Uint8Array, a TypedArray object. The Buffer class provides some extra functionalities and use cases.
In simple terms, ArrayBuffer represents a fixed-length contiguous memory area. The contents of ArrayBuffer cannot be modified or accessed directly. ArrayBuffers need TypedArray objects or DataView objects to access and manipulate the data inside it.
Creation and Initialization of Buffer vs ArrayBuffer
The most common ways of creating and initializing a NodeJS Buffer are as follows:
- alloc() method
- unSafeAlloc() method
- from() method
- fill() method
- write() method
Example: alloc(), unSafeAlloc() and from() Method
// Creates a Buffer filled with zeros of size 5 const buf1 = new Buffer.alloc(5); // Creates a Buffer of filled with 2 of size 5 const buf2 = new Buffer.alloc(5, 2); // Creates a Buffer of size 10 with values "abcedfgh==" and // UTF-8 encoding const buf22 = new Buffer.alloc(10, "abcedfgh==", "utf-8"); // Creates an uninitialized Buffer of size 5 faster than alloc // but needs to be filled or written to // and might contain ambigous data const buf3 = new Buffer.allocUnsafe(5); // Creates and initializes Buffer with 1, 2, 3, 4 from array const buf = new Buffer.from([1, 2, 3, 4]);
Example: fill() Method
const buf1 = Buffer.allocUnsafe(5).fill("a"); const buf2 = Buffer.alloc(10); buf2.fill("a", 1, 5, "utf-8"); console.log(buf1.toString()); console.log(buf2.toString());
Example: write() Method
const buf = Buffer.alloc(10); buf.write("abcd", 4); console.log(buf);
ArrayBuffer uses the ArrayBuffer() constructor to create ArrayBuffer objects.
// Creates an ArrayBuffer with a size of 10 bytes const buf = new ArrayBuffer(16); console.log(buf.byteLength); // Output: 10
An instance of Buffer is also an instance of TypedArray so all methods and properties of TypedArray are available to Buffer except for some incompatibilities. It is, for this inheritance, we can say that NodeJS Buffers are just a view for looking into the underlying ArrayBuffer. We can access the ArrayBuffer using the buffer property of the NodeJS Buffer.
const buf = Buffer.from("buffer", "utf-8"); const arr8 = new Uint8Array( buf.buffer, buf.byteOffset, buf.length / Uint8Array.BYTES_PER_ELEMENT ); console.log(arr8);
Accessing and Manipulating Data of Buffer vs ArrayBuffer
On the other hand, NodeJS Buffer doesn’t require any views for accessing or manipulating its contents but in some methods, it does require the provision of character encoding. Secondly, as we know NodeJS Buffer is a subclass of TypedArray, we can use the Buffer also as a view for the ArrayBuffer.
Example: Data access and manipulation of Buffer
// Data access and manipulation of Buffer const buf = Buffer.from("427566666572207673204172726179427566666572", "hex"); console.log(buf); console.log(buf.toString()); buf = 42 console.log(buf.toString());
Example: Data access and manipulation of ArrayBuffer
// Data access and manipulation of ArrayBuffer const buf = new ArrayBuffer(8); const view1 = new DataView(buf); const view2 = new Uint8Array(buf); // Uint8Array is a TypedArray view1.setUint8(0, 2) view2 = 2; console.log(view1.buffer); console.log(view2.buffer);
API of Buffer vs ArrayBuffer
Transferable Property of Buffer vs ArrayBuffer
ArrayBuffers are transferable objects, i.e their data/ownership can be transferred from one context to another. Take this as a pass-by-reference concept from C/C++ except that the transferring version is no longer available once it’s transferred to the new context. NodeJS Buffer in its entirety is not a transferable object.
Performance of Buffer vs ArrayBuffer
This performance aspect mainly depends on what you are trying to achieve with either of them and what data you decide to store. However, when dealing on the server side, NodeJS Buffer can be preferred. When a NodeJS Buffer is created it’s initialized to all 0’s. Whereas, the HTML5 spec states that the initialization of typed arrays must have their values set to 0. Allocating the memory and then setting all of the memory to 0s takes more time.