浅谈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对象。

相关推荐
酷酷的阿云2 分钟前
不用ECharts!从0到1徒手撸一个Vue3柱状图
前端·javascript·vue.js
微信:137971205874 分钟前
web端手机录音
前端
齐 飞10 分钟前
MongoDB笔记01-概念与安装
前端·数据库·笔记·后端·mongodb
神仙别闹27 分钟前
基于tensorflow和flask的本地图片库web图片搜索引擎
前端·flask·tensorflow
aPurpleBerry1 小时前
JS常用数组方法 reduce filter find forEach
javascript
GIS程序媛—椰子1 小时前
【Vue 全家桶】7、Vue UI组件库(更新中)
前端·vue.js
DogEgg_0011 小时前
前端八股文(一)HTML 持续更新中。。。
前端·html
ZL不懂前端1 小时前
Content Security Policy (CSP)
前端·javascript·面试
乐闻x2 小时前
ESLint 使用教程(一):从零配置 ESLint
javascript·eslint
木舟10092 小时前
ffmpeg重复回听音频流,时长叠加问题
前端