WebGL Tutorial
and more

Blob

撰写时间:2024-11-17

修订时间:2024-12-08

Blob

Blob,是Binary Large Object二进制大对象)的缩写。用于存储只读的原始二进制数据。在JavaScript中,Blob是一个对象。

创建URL

可使用Blob来存储ArrayBuffer, TypedArray等二进制数据,然后再调用URL.createObjectURL方法来创建一个URL

const { getHexAddrStrFromTypedArray } = await import('/js/esm/BinUtils.js'); let tarr = new Uint8Array([1, 2, 3, 4, 5]); pc.log('%s', getHexAddrStrFromTypedArray(tarr)); let blob = new Blob([tarr], {type: "application/octet-stream"}); pc.log(blob); let urlStr = URL.createObjectURL(blob); pc.log(urlStr); pc.appendHTMLStr(`Click to download`); //URL.revokeObjectURL(urlStr);

上面代码:

let blob = new Blob([tarr], {type: "application/octet-stream"});

使用tarr作为二进制数据源的一部分,创建了一个Blob对象,并将其MIME type指定为application/octet-stream

第一个参数是一个类如数组等可遍历的(iteratable)的对象,其成员类型可为ArrayBuffer, TypedArray, DataView, Blob,字符串等组合。注意,该参数须带有[],表示可以同时添加多个数组作为数据源。因此该参数实质是一个二维数组。上面代码如果误写为:

let blob = new Blob(tarr, ...);

则将导致tarr中的各个元素被拆分而分别识别为字符的ASCII值再添加进blob对象。

将其MIME type指定为application/octet-stream,这样在创建URL时,浏览器便可知道这是一个二进制流,在用户点击指向该URL指向的链接时,浏览器不会尝试在网页中显示出来,而是让用户直接下载。

然后调用URL.createObjectURL方法,将blob创建为一个URL对象,再返回指向该对象的字符串并赋值于urlStr。此字符串的开头包含了blob:https等协议标识。

最后,根据urlStr创建了一个a链接标签,这样当用户点击该链接时可予以下载。

通常情况下,调用URL.createObjectURL方法来创建的对象,可以网页被关闭后自动予以释放内存,也可显式调用URL.revokeObjectURL来及时释放内存。但由于我们将该URL制作了一个链接供用户点击,因此这里不能立即释放内存。

直接加载URL

上面在我们创建了URL后,可以直接调用fetch函数来加载该资源。

const { getHexAddrStrFromTypedArray } = await import('/js/esm/BinUtils.js'); let tarr = new Uint8Array([1, 2, 3, 4, 5]); let blob = new Blob([tarr], {type: "application/octet-stream"}); let urlStr = URL.createObjectURL(blob); fetch(urlStr) .then(response => { pc.log(response); return response.bytes(); /* return response.arrayBuffer(); return response.blob(); return response.text(); return response.json(); */ }).then(value => { pc.log(value); }) .catch(e => pc.showException(e.message)); URL.revokeObjectURL(urlStr);

fetch函数返回一个Promise对象,经解析后,返回Response对象。该对象有几个相关将数据解读为特定类型的方法:

  • arryBuffer()
  • blob()
  • bytes()
  • json()
  • text()

其中,bytes()返回一个解析后返回Uint8Array对象的Promise

直接使用Blob对象

读取不同的数据

可从Blob对象中直接读取出相应数据类型的数据:

  • arryBuffer()
  • bytes()
  • text():视为UTF-8格式读取
const { getHexAddrStrFromTypedArray } = await import('/js/esm/BinUtils.js'); let utf8Codes = new TextEncoder().encode('山海关'); pc.log(utf8Codes.constructor.name); pc.log('%s', getHexAddrStrFromTypedArray(utf8Codes)); let blob = new Blob([utf8Codes], {type: "text/plain"}); pc.log(blob); blob.text() .then(result => pc.log(result));

TextEncoderencode方法使用UTF-8来编码,所返回对象类型为Uint8ArrayBlobtext()方法返回一个解析后返回UTF-8格式字符串的Promise。因此,这两个方法可以很和谐地组合使用。

stream()方法

第一种方法:

const { getHexAddrStrFromTypedArray } = await import('/js/esm/BinUtils.js'); let utf8Codes = new TextEncoder().encode('山青水秀'); pc.log('%s', getHexAddrStrFromTypedArray(utf8Codes)); let blob = new Blob([utf8Codes], {type: "text/plain"}); let readableStream = blob.stream(); pc.log(readableStream); let reader = readableStream.getReader(); pc.log(reader); const {value, done} = await reader.read(); pc.log(value); pc.log(done);

第二种方法

const { getHexAddrStrFromTypedArray } = await import('/js/esm/BinUtils.js'); let utf8Codes = new TextEncoder().encode('山青水秀'); pc.log('%s', getHexAddrStrFromTypedArray(utf8Codes)); let blob = new Blob([utf8Codes], {type: "text/plain"}); let readableStream = blob.stream(); pc.log(readableStream); let reader = readableStream.getReader(); pc.log(reader); function process(obj) { if (obj.done) { pc.log('Reading stream finished'); return; } pc.log(obj.done); pc.log(obj.value); pc.log(obj.value.length); if (obj.value.length === 1) { pc.log(1); } if (obj.value.length === 2) { pc.log(2); } return reader.read().then(process); } reader.read().then(process);

第三种方法:创建一个字节reader, 再使用它来读取字节。

const { getHexAddrStrFromTypedArray } = await import('/js/esm/BinUtils.js'); let tarr = new Uint8Array([1, 2, 3, 4, 5]); let blob = new Blob([tarr], {type: "application/octet-stream"}); pc.log(blob); let urlStr = URL.createObjectURL(blob); fetch(urlStr) .then(response => { const reader = response.body.getReader(); }); URL.revokeObjectURL(urlStr);

参考资源

This site

  1. §ArrayBuffer in WebGL Tutorial

Specifications

  1. Streams
  2. Fetch

General

  1. Web IDL
  2. 数位 (百度百科)
  3. MIME types (MDN)
  4. URL.createObjectURL (MDN)
  5. Streams API (MDN)
  6. Blob (MDN)
  7. Using readable streams (MDN)

TypedArray

  1. JavaScript typed arrays (MDN)
  2. Faster Canvas Pixel Manipulation with Typed Arrays
  3. Endianness (MDN)