What is the difference between an ArrayBuffer and a Blob?
Asked Answered
M

3

121

I'm reading http://www.html5rocks.com/en/tutorials/file/xhr2/ and trying to figure out the difference between an ArrayBuffer and a Blob.

Aren't both containers comprised of bits? Hence, couldn't both containers be viewed in many ways (as 32-bit chunks, 16-bit chunks, etc.)?

Mayoralty answered 5/8, 2012 at 23:49 Comment(1)
ArrayBuffer (and its Views such as DataView and Typed arrays) for binary data, Blob for binary files.Gonzalo
P
25

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':

Puritanism answered 5/8, 2012 at 23:51 Comment(8)
Hmm, but couldn't you view both in different ways as well since they are both containers of bits essentially?Mayoralty
Sure .. but I'm guessing an ArrayBuffer has readily available functions for it? a BLOB can be anything, an ArrayBuffer is well defined structure.Puritanism
Ah, ok, so an ArrayBuffer just exposes an interface for doing that.Mayoralty
Still not clear, to be honest. What do you mean by can "a BLOB can be anything?". Ain't it just a sequence of bytes, just like ArrayBuffer?Poleaxe
An ArrayBuffer is in the memory, available for manipulation. A Blob can be on disk, in cache memory, and other places not readily available. But the data from a Blob can be copied into an ArrayBuffer.Parasol
I can't find any information on performance implications of converting between these. If you have a Blob that is known to be in memory, does converting to an ArrayBuffer (using Response() or the new Blob.arrayBuffer() or other means) copy the data, or return a reference to it? And similarly the other direction: if you have an ArrayBuffer and want a Blob of it, does that copy the data or not?Maser
@BartvanHeukelom, citation needed.Mott
explanation of "Blob": if you want to work directly with a Blob, then ... this is called a recursive explanationLesialesion
S
134

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 ArrayBuffer can be changed (e.g. with a DataView)
    • a Blob is immutable
  • Source / Availability in Memory
    • 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
  • Convert / Generate
  • Use in Other Libraries
    • jsZip; (new JSZip()).loadAsync(...) accepts both ArrayBuffer and Blob: String/Array of bytes/ArrayBuffer/Uint8Array/Buffer/Blob/Promise
  • How does protocol handle ArrayBuffer vs Blob
    • Websocket (aka WS / WSS)
      • Use the webSocket's binaryType property (could have values "arraybuffer" or "blob") to "control the type of binary data being received over the WebSocket connection."
    • XmlHttpRequest (aka XHR)
      • Use the xhr's responseType property 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.

Other helpful documentation:

The ArrayBuffer object is used to represent a generic, fixed-length raw binary data buffer. You cannot directly manipulate the contents of an ArrayBuffer; instead, you create one of the typed array objects or a DataView object which represents the buffer in a specific format, and use that to read and write the contents of the buffer.

A Blob object represents a file-like object of immutable, raw data. Blob represent data that isn't necessarily in a JavaScript-native format. The File interface is based on Blob, inheriting blob functionality and expanding it to support files on the user's system.

Selangor answered 10/10, 2016 at 5:0 Comment(8)
As I just found out when I got a binary response from a websocket you get a Blob there - and the disadvantage of the Blob seems to be that you cannot even read it. It's just a handle. I needed to get a few bytes from that blob. You need to create a FileReader, see "Example for extracting data from a Blob" here - which adds yet another asynchronous function before you can access anything from your Blob.Cinerary
Thanks, @Mörre , I incorporated your comment. I guess that's consistent with the documentation: A Blob object represents a file-like object, but I explicitly added that Blobs may need some kind of "access layer" (before the edit, I implied Blobs didn't need any "access layer")Selangor
arrayBuffer can be converted to Blob as mentioned in this answer like this: new Blob([new Uint8Array(data)]); I tested it, and it works for PNG images.Overreact
@Mörre You can slice a blob to return a new blob containing just the bytes you want and then read that. If you want real performance then workers support synchronous file reading and you can transfer ownership of (instead of cloning) ArrayBuffers between workers and window processes almost instantlyUigur
A Blob can also be converted to ArrayBuffer with the async method blob.arraybuffer() e.g. const buffer = await blobFile.arrayBuffer() developer.mozilla.org/en-US/docs/Web/API/Blob/arrayBufferNates
"Blob can become" no, as you said before, it's immutable, so it cannot become anything. You can generate an ArrayBuffer from a Blob, or a Blob from an ArrayBuffer, but in both case, you duplicate the data, nothing becomes something else.Herdsman
Thanks @Kaiido, I will change the language to "generate an ArrayBuffer from a Blob"Selangor
@Mörre FWIW when creating the websocket you can specify if you want it to output binary data as Blobs or as ArrayBuffers, see hereNasturtium
P
25

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':

Puritanism answered 5/8, 2012 at 23:51 Comment(8)
Hmm, but couldn't you view both in different ways as well since they are both containers of bits essentially?Mayoralty
Sure .. but I'm guessing an ArrayBuffer has readily available functions for it? a BLOB can be anything, an ArrayBuffer is well defined structure.Puritanism
Ah, ok, so an ArrayBuffer just exposes an interface for doing that.Mayoralty
Still not clear, to be honest. What do you mean by can "a BLOB can be anything?". Ain't it just a sequence of bytes, just like ArrayBuffer?Poleaxe
An ArrayBuffer is in the memory, available for manipulation. A Blob can be on disk, in cache memory, and other places not readily available. But the data from a Blob can be copied into an ArrayBuffer.Parasol
I can't find any information on performance implications of converting between these. If you have a Blob that is known to be in memory, does converting to an ArrayBuffer (using Response() or the new Blob.arrayBuffer() or other means) copy the data, or return a reference to it? And similarly the other direction: if you have an ArrayBuffer and want a Blob of it, does that copy the data or not?Maser
@BartvanHeukelom, citation needed.Mott
explanation of "Blob": if you want to work directly with a Blob, then ... this is called a recursive explanationLesialesion
I
2

If you are dealing with something that is more similar to an immutable file that may be retrieved, stored, or served as a file over HTTP, a Blob has a useful feature: blob.type (Web API docs, Nodejs docs). This returns a MIME type (such as image/png) that you can you use for your Content-Type HTTP header when serving the blob.

Indetermination answered 8/5, 2022 at 17:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.