浅谈ArrayBuffer、Blob和File、FileReader

ArrayBuffer、Blob和File都是JavaScript中处理二进制数据的对象。

ArrayBuffer

用于表示一个通用的、固定长度的原始二进制数据缓冲区。它不能直接操作缓冲区中的数据,而需要通过一个类型化数组TypedArray (如Int8Array、Uint8Array等)或者一个数据视图DataViews(如Float32Array、Uint16Array等)来操作。

Blob

用于表示不可变的原始数据块的类文件对象。它可以是任意类型的数据,如文本、图片、音频、视频等。Blob对象通常用于存储大块的数据,并且可以在需要时进行下载或上传,它的数据可以按文本或二进制的格式进行读取。

javascript 复制代码
new Blob(array, options);

除了使用Blob()构造函数来创建blob 对象之外,还可以从 blob 对象中创建blob,也就是将 blob 对象切片。Blob 对象内置了 slice() 方法用来将 blob 对象分片。

javascript 复制代码
const blob = instanceOfBlob.slice([start [, end [, contentType]]]};

File

文件(File)接口提供有关文件的信息,并允许网页中的 JavaScript 访问其内容。实际上,File 对象是特殊类型的 Blob,且可以用在任意的 Blob 类型的 context 中。Blob 的属性和方法都可以用于 File 对象。用于表示用户通过<input type="file">元素选择的文件。它通常用于读取用户上传的文件内容,或者用于构建FileList对象,后者可以用于<input type="file">元素的multiple属性。

FileReader

FileReader 是一个异步 API,用于读取文件并提取其内容以供进一步使用。FileReader 可以将 Blob 读取为不同的格式。

FileReader 仅用于以安全的方式从用户系统读取文件内容,不能用于从文件系统中按路径名简单地读取文件。

javascript 复制代码
<input type="file" id="fileInput" />

<img id="preview" />

const fileInput = document.getElementById("fileInput");
const preview = document.getElementById("preview");
const reader = new FileReader();

fileInput.onchange = (e) => {
  reader.readAsDataURL(e.target.files[0]);
  // 效果相同
  // preview.src = URL.createObjectURL(e.target.files[0])
};

reader.onload = (e) => {
  preview.src = e.target.result;
  console.log(e.target.result);
};

FileReader 对象提供了以下方法来加载文件:

  • readAsArrayBuffer():读取指定 Blob 中的内容,完成之后,result 属性中保存的将是被读取文件的 ArrayBuffer 数据对象;
  • FileReader.readAsBinaryString():读取指定 Blob 中的内容,完成之后,result 属性中将包含所读取文件的原始二进制数据;
  • FileReader.readAsDataURL():读取指定 Blob 中的内容,完成之后,result 属性中将包含一个data: URL 格式的 Base64 字符串以表示所读取文件的内容。
  • FileReader.readAsText():读取指定 Blob 中的内容,完成之后,result 属性中将包含一个字符串以表示所读取的文件内容。

可以看到,上面这些方法都接受一个要读取的 blob 对象作为参数,读取完之后会将读取的结果放入对象的 result 属性中。

FileReader 对象常用的事件如下:

  • abort:该事件在读取操作被中断时触发;
  • error:该事件在读取操作发生错误时触发;
  • load:该事件在读取操作完成时触发;
  • progress:该事件在读取 Blob 时触发。

当然,这些方法可以加上前置 on 后在HTML元素上使用,比如onloadonerroronabortonprogress。除此之外,由于FileReader对象继承自EventTarget,因此还可以使用 addEventListener() 监听上述事件。

Object URL

Object URL(MDN定义名称)又称Blob URL(W3C定义名称),是HTML5中的新标准。它是一个用来表示File Object 或Blob Object 的URL。在网页中,我们可能会看到过这种形式的 Blob URL:

其实 Blob URL/Object URL 是一种伪协议,允许将 Blob 和 File 对象用作图像、二进制数据下载链接等的 URL 源。

对于 Blob/File 对象,可以使用 URL构造函数的 createObjectURL() 方法创建将给出的对象的 URL。这个 URL 对象表示指定的 File 对象或 Blob 对象。我们可以在<img><script> 标签中或者 <a><link> 标签的 href 属性中使用这个 URL。

javascript 复制代码
const fileInput = document.getElementById("fileInput");
const preview = document.getElementById("preview");

fileInput.onchange = (e) => {
  preview.src = URL.createObjectURL(e.target.files[0]);
  console.log(preview.src);
};

当我们使用createObjectURL()方法创建一个data URL 时,就需要使用revokeObjectURL()方法从内存中清除它来释放内存。虽然浏览器会在文档卸载时自动释放 Data URL,但为了提高性能,我们应该使用createObjectURL()来手动释放它。revokeObjectURL()方法接受一个Data URL 作为其参数,返回undefined

Base64

Base64 是一种基于64个可打印字符来表示二进制数据的表示方法。Base64 编码普遍应用于需要通过被设计为处理文本数据的媒介上储存和传输二进制数据而需要编码该二进制数据的场景。这样是为了保证数据的完整并且不用在传输过程中修改这些数据。

  • atob():解码,解码一个 Base64 字符串;
  • btoa():编码,从一个字符串或者二进制数据编码一个 Base64 字符串。
javascript 复制代码
var aBlob = new Blob( array, options );
btoa("JavaScript")       // 'SmF2YVNjcmlwdA=='
atob('SmF2YVNjcmlwdA==') // 'JavaScript'

base64 的实际应用场景

其实多数场景就是基于Data URL的。比如,使用toDataURL()方法把 canvas 画布内容生成 base64 编码格式的图片:

const canvas = document.getElementById('canvas'); 
const ctx = canvas.getContext("2d");
const dataUrl = canvas.toDataURL();

ArrayBuffer、Blob和File之间的关系是,你可以通过File对象获取到Blob对象,然后通过Blob对象获取到ArrayBuffer对象。例如,你可以使用FileReader对象的readAsArrayBuffer方法将File对象读取为ArrayBuffer对象。反过来,你可以通过创建一个新的Blob对象,然后使用它来创建一个新的File对象,从而将ArrayBuffer对象转换为File对象。

相关推荐
@解忧杂货铺30 分钟前
前端vue如何实现数字框中通过鼠标滚轮上下滚动增减数字
前端·javascript·vue.js
F-2H2 小时前
C语言:指针4(常量指针和指针常量及动态内存分配)
java·linux·c语言·开发语言·前端·c++
gqkmiss3 小时前
Chrome 浏览器插件获取网页 iframe 中的 window 对象
前端·chrome·iframe·postmessage·chrome 插件
m0_748247555 小时前
Web 应用项目开发全流程解析与实战经验分享
开发语言·前端·php
m0_748255025 小时前
前端常用算法集合
前端·算法
真的很上进6 小时前
如何借助 Babel+TS+ESLint 构建现代 JS 工程环境?
java·前端·javascript·css·react.js·vue·html
web130933203986 小时前
vue elementUI form组件动态添加el-form-item并且动态添加rules必填项校验方法
前端·vue.js·elementui
NiNg_1_2346 小时前
Echarts连接数据库,实时绘制图表详解
前端·数据库·echarts
如若1237 小时前
对文件内的文件名生成目录,方便查阅
java·前端·python
滚雪球~7 小时前
npm error code ETIMEDOUT
前端·npm·node.js