Instances of Buffer are also instances of Uint8Array in node.js 4.x and higher. Thus, the most efficient solution is to access the buffer's own .buffer property directly, as per https://stackoverflow.com/a/31394257/1375574. The Buffer constructor also takes an ArrayBufferView argument if you need to go the other direction.
Note that this will not create a copy, which means that writes to any ArrayBufferView will write through to the original Buffer instance.
In older versions, node.js has both ArrayBuffer as part of v8, but the Buffer class provides a more flexible API. In order to read or write to an ArrayBuffer, you only need to create a view and copy across.
From Buffer to ArrayBuffer:
function toArrayBuffer(buffer) {
const arrayBuffer = new ArrayBuffer(buffer.length);
const view = new Uint8Array(arrayBuffer);
for (let i = 0; i < buffer.length; ++i) {
view[i] = buffer[i];
}
return arrayBuffer;
}
From ArrayBuffer to Buffer:
function toBuffer(arrayBuffer) {
const buffer = Buffer.alloc(arrayBuffer.byteLength);
const view = new Uint8Array(arrayBuffer);
for (let i = 0; i < buffer.length; ++i) {
buffer[i] = view[i];
}
return buffer;
}
Answer from Martin Thomson on Stack Overflownode.js - Convert a binary NodeJS Buffer to JavaScript ArrayBuffer - Stack Overflow
javascript - What is the difference between an array and an ArrayBuffer? - Stack Overflow
typed arrays: make Buffers and ArrayBuffers interchangeable?
javascript - What is the difference between an ArrayBuffer and a Blob? - Stack Overflow
Instances of Buffer are also instances of Uint8Array in node.js 4.x and higher. Thus, the most efficient solution is to access the buffer's own .buffer property directly, as per https://stackoverflow.com/a/31394257/1375574. The Buffer constructor also takes an ArrayBufferView argument if you need to go the other direction.
Note that this will not create a copy, which means that writes to any ArrayBufferView will write through to the original Buffer instance.
In older versions, node.js has both ArrayBuffer as part of v8, but the Buffer class provides a more flexible API. In order to read or write to an ArrayBuffer, you only need to create a view and copy across.
From Buffer to ArrayBuffer:
function toArrayBuffer(buffer) {
const arrayBuffer = new ArrayBuffer(buffer.length);
const view = new Uint8Array(arrayBuffer);
for (let i = 0; i < buffer.length; ++i) {
view[i] = buffer[i];
}
return arrayBuffer;
}
From ArrayBuffer to Buffer:
function toBuffer(arrayBuffer) {
const buffer = Buffer.alloc(arrayBuffer.byteLength);
const view = new Uint8Array(arrayBuffer);
for (let i = 0; i < buffer.length; ++i) {
buffer[i] = view[i];
}
return buffer;
}
To go the opposite way (from ArrayBuffer to Buffer):
var buffer = Buffer.from( new Uint8Array(arrayBuffer) );
Summary
Unless you need the ability to write/edit (using an ArrayBuffer), then Blob format is probably best.
Detail
I came to this question from a different html5rocks page., and I found @Bart van Heukelom's comments to be helpful, so I wanted to elevate them to an answer here.
I also found helpful resources specific to ArrayBuffer and Blob objects. In summary: despite the emphasis on Blob being immutable/"raw data" Blob objects are easy to work with.
Resources that compare / contrast ArrayBuffer vs Blob:
- Mutability
- an
ArrayBuffercan be changed (e.g. with aDataView) - a
Blobis immutable
- an
- Source / Availability in Memory
- Quoting Bart van Heukelom:
- An ArrayBuffer is in the memory, available for manipulation.
- A Blob can be on disk, in cache memory, and other places not readily available
- Access Layer
ArrayBufferwill require some access layer like typed arraysBlobcan be passed directly into other functions likewindow.URL.createObjectURL, as seen in the example from OP's URL.- However, as Mörre points out you may still need
File-related interfaces and API's likeFileReaderto work with a Blob.
- However, as Mörre points out you may still need
- Convert / Generate
- You can generate
BlobfromArrayBufferand vice versa, which addresses the OP's "Aren't both containers comprised of bits?" - ArrayBuffer can be generated from a Blob using the
FileReader'sreadAsArrayBuffermethod , or the async methodconst arrayBuffer = await blob.arrayBuffer()(thanks to @Darren G) - Blob can be generated from an ArrayBuffer as @user3405291 points out
new Blob([new Uint8Array(data)]);, shown in this answer
- You can generate
- Use in Other Libraries
jsZip;(new JSZip()).loadAsync(...)accepts bothArrayBufferandBlob:String/Array of bytes/ArrayBuffer/Uint8Array/Buffer/Blob/Promise
- How does protocol handle ArrayBuffer vs Blob
- Websocket (aka WS / WSS)
- Use the webSocket's
binaryTypeproperty (could have values "arraybuffer" or "blob") to "control the type of binary data being received over the WebSocket connection."
- Use the webSocket's
- XmlHttpRequest (aka XHR)
- Use the xhr's
responseTypeproperty to "to change the expected response type from the server" (valid values include "arraybuffer", "blob", and others like "document", "json", and "text") -
the response property will contain the entity body according to
responseType, as an ArrayBuffer, Blob, Document, JSON, or string.
- Use the xhr's
- Websocket (aka WS / WSS)
Other helpful documentation:
ArrayBuffer
The
ArrayBufferobject is used to represent a generic, fixed-length raw binary data buffer. You cannot directly manipulate the contents of anArrayBuffer; instead, you create one of the typed array objects or aDataViewobject which represents the buffer in a specific format, and use that to read and write the contents of the buffer.
Blob
A
Blobobject represents a file-like object of immutable, raw data.Blobrepresent data that isn't necessarily in a JavaScript-native format. TheFileinterface is based onBlob, inheriting blob functionality and expanding it to support files on the user's system.
It's explained on the page.
ArrayBuffer
An ArrayBuffer is a generic fixed-length container for binary data. They are super handy if you need a generalized buffer of raw data, but the real power behind these guys is that you can create "views" of the underlying data using JavaScript typed arrays. In fact, multiple views can be created from a single ArrayBuffer source. For example, you could create an 8-bit integer array that shares the same ArrayBuffer as an existing 32-bit integer array from the same data. The underlying data remains the same, we just create different representations of it.
BLOB
If you want to work directly with a Blob and/or don't need to manipulate any of the file's bytes, use xhr.responseType='blob':