概述
- Blob: Blob对象表示一个不可变、原始数据的类文件对象。它的数据可以按文本或二进制格式进行读取,也可以转换成ReadableStream来进行数据操作。
- ArrayBuffer: ArrayBuffer对象用来表示通用的、固定长度的原始二进制数据缓冲区。
- Buffer: Buffer对象来自Nodejs,表示固定长度的字节序列。
关系图
Blob
Blob用来支持文件操作。
File对象继承自Blob,拥有Blob所有的属性和方法,同时又有自己独特的属性和方法。
File对象是来自用户在一个input
元素上选择文件后返回的FileList对象,也可以是来自由拖放操作生成的DataTransfer对象,或者来自 HTMLCanvasElement上的 mozGetAsFile
() API。
语法
var aBlob = new Blob( array, options );
var aFileParts = ['<a id="a"><b id="b">hey!</b></a>']; // 一个包含DOMString的数组
var oMyBlob = new Blob(aFileParts, {type : 'text/html'}); // 得到 blob
- array:是一个由ArrayBuffer, ArrayBufferView, Blob, DOMString 等对象构成的 Array。
- options 是一个可选的BlobPropertyBag字典,它可能会指定如下两个属性:
– type,默认值为 “”,它代表了将会被放入到blob中的数组内容的MIME类型。(DOMStrings会被编码为UTF-8)
– endings,默认值为"transparent",用于指定包含行结束符\n的字符串如何被写入。 它是以下两个值中的一个: “native”,代表行结束符会被更改为适合宿主操作系统文件系统的换行符,或者 “transparent”,代表会保持blob中保存的结束符不变
属性
- Blob.size(只读):Blob对象中所包含数据的大小(字节)。
- Blob.type(只读):字符串 ,表示Blob对象所包含的MiME类型。类型未知则为空值。
方法
- slice:返回一个包含源bloc对象指定范围内数据的新bloc对象。
- stream:返回一个能读取blob内容的ReadableStream。
- text:返回一个包含所有内容的UTF-8格式的USVString的promise。
- arrayBuffer:返回一个包含blob所有内容的二进制格式的 ArrayBuffer的promise。
功能
- 文件下载: 通过URL.createObjectURL(blob)生成Blob URL,赋值给a.download属性
- 图片显示出: 通过URL.createObjectURL(blob)生成Blob URL,赋值给img.src属性
- 资源分段上传: 通过blob.slice分割二进制数据为子blob对象
- 本地文件读取: FileReader的api可以将Blob或者File对象转化成文本、ArrayBuffer、Data URL等
Blob实现文件下载
通过window.createObjectURL,接收一个Blob(File)对象,将其转化成Blob URL,然后再赋值给a.download属性,在页面上点击a标签即可实现文件下载。
<!-- html部分 -->
<a id="h">点此进行下载</a>
<!-- js部分 -->
<script>
var blob = new Blob(["Hello World"]);
var url = window.URL.createObjectURL(blob);
var a = document.getElementById("h");
a.download = "helloworld.txt";
a.href = url;
</script>
Blob实现本地图片展示
<!-- html部分 -->
<input type="file" id='f' />
<img id='img' style="width: 200px;height:200px;" />
<!-- js部分 -->
<script>
document.getElementById('f').addEventListener('change', function (e) {
var file = this.files[0];
const img = document.getElementById('img');
const url = window.URL.createObjectURL(file);
img.src = url;
img.onload = function () {
// 释放一个之前通过调用 URL.createObjectURL创建的 URL 对象
window.URL.revokeObjectURL(url);
}
}, false);
</script>
Blob读取本地文件内容
如果想要读取Blob对象或者文件对象并转化为其他格式的数据,可以借助FileReader对象的API进行操作
- FileReader.readAsText(Blob):将Blob转化为文本字符串
- FileReader.readAsArrayBuffer(Blob): 将Blob转为ArrayBuffer格式数据
- FileReader.readAsDataURL(): 将Blob转化为Base64格式的Data URL
ArrayBuffer
ArrayBuffer是一个字节数组。不能直接操作ArrayBuffer的内容,只能通过类型数组对象或DataView对象来操作,它们会将缓冲区的数据表示为特定的格式,并通过这些格式来读写缓冲区的内容。
产生背景
与WebGL项目有关,传统文本格式通信,要对信息进行二进制格式化,为提高浏览器与显卡之间的通信速度,采用直接传递二进制数据的方式,通信速度大幅提升。
语法
new ArrayBuffer(length) // 返回一个指定大小的ArrayBuffer对象
- length :要创建的ArrayBuffer的大小,单位为字节。
属性
- byteLength:表示当前实例占用的内存字节长度(只读)
const buffer = new ArrayBuffer(32);
buffer.byteLenfth; // 32
方法
- isView:如果参数是 ArrayBuffer 的视图实例则返回true,例如类型数组对象或DataView对象,否则返回false
- slice(begin,end):返回一个新的ArrayBuffer,内容是字节副本,从begin(包括),到 end(不包括)
功能
读取: 通过FileReader将文件转化成ArrayBuffer数据
写入:通过TypedArray或DataView对象进行操作
通过ArrayBuffer读取本地数据
document.getElementById('f').addEventListener('change', function (e) {
const file = this.files[0];
const fileReader = new FileReader();
fileReader.onload = function () {
const result = fileReader.result;
console.log(result)
}
fileReader.readAsArrayBuffer(file);
}, false);
通过TypeArray对ArrayBuffer进行写操作
const typedArray1 = new Int8Array(8);
typedArray1[0] = 32;
const typedArray2 = new Int8Array(typedArray1);
typedArray2[1] = 42;
console.log(typedArray1);
// output: Int8Array [32, 0, 0, 0, 0, 0, 0, 0]
console.log(typedArray2);
// output: Int8Array [32, 42, 0, 0, 0, 0, 0, 0]
通过DataView对ArrayBuffer进行写操作
const buffer = new ArrayBuffer(16);
const view = new DataView(buffer);
view.setInt8(2, 42);
console.log(view.getInt8(2));
// 输出: 42
与原生数组的区别
长度 | 存放地方 | 操作数据方法 | 只读 | |
---|---|---|---|---|
ArrayBuffer | 固定 | 栈 | 无 | √ |
Array | 可以自由增减 | 堆 | push/pop | × |
Buffer
Nodejs提供的对象,前端没有。一般用于IO操作。例如前端请求数据的时候,可以通过Buffer对接收到的前端数据进行整合。
工作流程图
功能
node端接收请求数据
// Node端
const app = new Koa();
app.use(async (ctx, next) => {
if (ctx.path === '/ajax') {
const chunks = [];
const req = ctx.req;
req.on('data', buf => {
chunks.push(buf);
})
req.on('end', () => {
let buffer = Buffer.concat(chunks);
console.log(buffer.toString())
})
}
});
app.listen(3000)
// 请求
const xhr = new XMLHttpRequest();
xhr.open("POST", "ajax", true);
xhr.setRequestHeader('Content-Type', 'text/plain')
xhr.send("asdfgghjhjkttyuerttwerweqr");