阅读 539

读懂前端二进制系列-1. 读取Blob

「本文已参与好文召集令活动,点击查看:后端、大前端双赛道投稿,2万元奖池等你挑战!

上周,写了2篇关于资源下载保存的文章,一篇是在资源不超过浏览器Blob大小限制并且浏览器RAM够的情况下,另一篇是如何突破浏览器内存限制保存下载超大资源文件(超过2G)。感兴趣的话,可以看看。本系列是对上面2篇文章的一个扩展,通过Blob/File扩展出所有可能存在的类型,属于个人学习笔记。

传送门:
再看资源文件下载保存,如何健壮?
前端自个突破浏览器Blob和RAM大小限制保存文件的骚玩法!

概览

下面是一张关于二进制数据相关数据类型的可转换的图片,下面我们按流程指向学习,
本篇文章写:读取BlobArrayBuffer或者Data URLWechatIMG21.jpeg

  1. Blob

Blob 对象表示一个不可变、原始数据的类文件对象。它的数据可以按文本或二进制的格式进行读取,也可以转换成 [ReadableStream] 来用于数据操作。

  1. ArrayBuffer

ArrayBuffer 对象用来表示通用的、固定长度的原始二进制数据缓冲区。它是一个字节数组,通常在其他语言中称为“byte array”。你不能直接操作 ArrayBuffer 的内容,而是要通过[类型数组对象]或 [DataView] 对象来操作,它们会将缓冲区中的数据表示为特定的格式,并通过这些格式来读写缓冲区的内容。

  1. DataURLs

Data URLs,即前缀为 data: 协议的URL,其允许内容创建者向文档中嵌入小文件。Data URLs 由四个部分组成:前缀(data:)、指示数据类型的MIME类型、如果非文本则为可选的base64标记、数据本身:

data:[<mediatype>][;base64],<data>
复制代码

了解完基本类型概念,下面就看看如何读取Blob,当然了,Js中并没有直接读取Blob数据的方法,所以需要一些转换。 ,否则本文就没有意义了。

实现

1. Blob.arrayBuffer

通过Blob.arrayBuffer()它会返回一个promise对象,包含blob所有内容的二进制格式arraybuffer

var debug = {hello: "world"};
var blob = new Blob([JSON.stringify(debug, null, 2)], {type : 'application/json'});
// 异步获取
blob.arrayBuffer().then(arraybuffer=>console.log(arraybuffer))
复制代码

2. 借助FileReader

FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 [File] 或 [Blob] 对象指定要读取的文件或数据。它暴露了几个api,可以以如下方式读取Blob中的内容。

  1. readAsArrayBuffer:读取后,result属性保存的是arraybuffer数据对象
  2. readAsBinaryString:读取后,result属性保存原始二进制数据
  3. readAsDataURL:读取后,result属性包含一个data:URL 格式的base64字符串
  4. readAsText():读取后,result属性包含一个字符串
var reader = new FileReader();
// 读取结束触发
reader.addEventListener("loadend", function() {
   // reader.result 包含被转化为类型数组 typed array 的 blob
});
reader.readAsArrayBuffer(blob);
复制代码

3. Response构造函数

Fetch API的 Response 接口呈现了对一次请求的响应数据。你可以使用Response.Response() 构造函数来创建一个 Response 对象。

let myResponse = new Response(body, init);
复制代码

body参数可选,也可以为null,或者是下面一个:

  • Blob
  • BufferSource
  • FormData
  • ReadableStream
  • URLSearchParams
  • USVString

所以可以通过该构造函数读取Blob,当然类型得对得上:

var text = await (new Response(blob)).text();
var arrayBuffer = await (new Response(blob)).arrayBuffer();
var json = await (new Response(blob)).json();
复制代码

4. 扩展ReadableStream

流操作API中的ReadableStream接口呈现了一个可读取的二进制流操作。Fetch API通过Response的属性body提供了一个具体的ReadableStream对象。

fetch("https://www.example.org/").then((response) => {
  // 创建一个读取器并将流锁定于其上,一旦被锁定,其他读取器不能读取它,直至它被释放。
  const reader = response.body.getReader();
  const stream = new ReadableStream({
    start(controller) {
      // 下面的函数处理每个数据块
      function push() {
        // "done"是一个布尔型,"value"是一个Uint8Array
        reader.read().then(({ done, value }) => {
          // 判断是否还有可读的数据?
          if (done) {
            // 告诉浏览器已经结束数据发送
            controller.close();
            return;
          }

          // 取得数据并将它通过controller发送给浏览器
          controller.enqueue(value);
          push();
        });
      };

      push();
    }
  });

  return new Response(stream, { headers: { "Content-Type": "text/html" } });
});
复制代码

总结

这便是读取Blob的几种方式,下一篇就计划看看ArrayBuffer和TypeArray。最后关于读取流相关,建议看看传送门:前端自个突破浏览器Blob和RAM大小限制保存文件的骚玩法!,这里有实战。

再最后,客户留个赞呗!带你五点重温JS宝典~

文章分类
前端
文章标签