arrayBuffer、blob、file对象
总结一下 ArrayBuffer Blob File 三种对象的特性,区别。
# ArrayBuffer
ArrayBuffer 对象用来表示通用的、固定长度的原始二进制数据缓冲区。它是一个字节数组,通常在其他语言中称为“byte array”。
新建一个 ArrayBuffer 对象
// 语法
new ArrayBuffer(length) // length 要创建的 ArrayBuffer 的大小,单位为字节。
2
ArrayBuffer 对象有实例属性 byteLength,表示当前实例占用的内存长度(单位字节)。
let buffer = new ArrayBuffer(8)
buffer.byteLength // 8
2
3
ArrayBuffer 对象有实例方法 slice(),用来复制一部分内存。它接受两个整数参数,分别表示复制的开始位置(从 0 开始)和结束位置(复制时不包括结束位置),如果省略第二个参数,则表示一直复制到结束。
var buf1 = new ArrayBuffer(8)
var buf2 = buf1.slice(0)
2
# Blob 对象
Blob 对象表示一个二进制文件的数据内容,比如一个图片文件的内容就可以通过 Blob 对象读写。它通常用来读写文件,它的名字是 Binary Large Object (二进制大型对象)的缩写。它与 ArrayBuffer 的区别在于,它用于操作二进制文件,而 ArrayBuffer 用于操作内存。
浏览器原生提供 Blob()构造函数,用来生成实例对象。
new Blob(array [, options])
2
Blob 构造函数接受两个参数。第一个参数是数组,成员是字符串或二进制对象,表示新生成的 Blob 实例对象的内容;第二个参数是可选的,是一个配置对象,目前只有一个属性 type,它的值是一个字符串,表示数据的 MIME 类型,默认是空字符串。
var htmlFragment = ['<a id="a"><b id="b">hey!</b></a>']
var myBlob = new Blob(htmlFragment, { type: 'text/html' })
2
实例对象 myBlob 包含的是字符串。生成实例的时候,数据类型指定为 text/html。
Blob 保存 JSON 数据。
var obj = { hello: 'world' }
var blob = new Blob([JSON.stringify(obj)], { type: 'application/json' })
2
实例属性和实例方法
Blob 具有两个实例属性 size 和 type,分别返回数据的大小和类型。
var htmlFragment = ['<a id="a"><b id="b">hey!</b></a>']
var myBlob = new Blob(htmlFragment, { type: 'text/html' })
myBlob.size // 32
myBlob.type // "text/html"
2
3
4
5
Blob 具有一个实例方法 slice,用来拷贝原来的数据,返回的也是一个 Blob 实例。
myBlob.slice(start, end, contentType)
slice 方法有三个参数,都是可选的。它们依次是起始的字节位置(默认为 0)、结束的字节位置(默认为 size 属性的值,该位置本身将不包含在拷贝的数据之中)、新实例的数据类型(默认为空字符串)
获取文件信息
文件选择器<input type="file">用来让用户选取文件。出于安全考虑,浏览器不允许脚本自行设置这个控件的 value 属性,即文件必须是用户手动选取的,不能是脚本指定的。一旦用户选好了文件,脚本就可以读取这个文件。
文件选择器返回一个 FileList 对象,该对象是一个类似数组的成员,每个成员都是一个 File 实例对象。File 实例对象是一个特殊的 Blob 实例,增加了 name 和 lastModifiedDate 属性。
// HTML 代码如下
// <input type="file" accept="image/*" multiple onchange="fileinfo(this.files)"/>
function fileinfo(files) {
for (var i = 0; i < files.length; i++) {
var f = files[i]
console.log(
f.name, // 文件名,不含路径
f.size, // 文件大小,Blob 实例属性
f.type, // 文件类型,Blob 实例属性
f.lastModifiedDate // 文件的最后修改时间
)
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
除了文件选择器,拖放 API 的 dataTransfer.files 返回的也是一个 FileList 对象,它的成员因此也是 File 实例对象。
Ajax responseType
AJAX 请求时,如果指定 responseType 属性为 blob,下载下来的就是一个 Blob 对象。
function getBlob(url, callback) {
var xhr = new XMLHttpRequest()
xhr.open('GET', url)
xhr.responseType = 'blob'
xhr.onload = function() {
callback(xhr.response)
}
xhr.send(null)
}
2
3
4
5
6
7
8
9
客户端下载文件
// 输入blob和fileName 自动下载文件
function downloadFile(myBlob, fileName) {
const blobURL: any = window.URL.createObjectURL(myBlob)
const tempLink: any = document.createElement('a')
tempLink.style.display = 'none'
tempLink.href = blobURL
tempLink.setAttribute('download', fileName)
if (typeof tempLink.download === 'undefined') {
tempLink.setAttribute('target', '_blank')
}
document.body.appendChild(tempLink)
tempLink.click() // 手动触发下载
document.body.removeChild(tempLink) // remove dom
window.URL.revokeObjectURL(blobURL) // remove ObjectURL
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
浏览器处理 Blob URL 就跟普通的 URL 一样,如果 Blob 对象不存在,返回 404 状态码;如果跨域请求,返回 403 状态码。Blob URL 只对 GET 请求有效,如果请求成功,返回 200 状态码。由于 Blob URL 就是普通 URL,因此可以下载。
读取文件
取得 Blob 对象以后,可以通过FileReader对象,读取 Blob 对象的内容,即文件内容。
FileReader 对象提供四个方法,处理 Blob 对象。Blob 对象作为参数传入这些方法,然后以指定的格式返回。
- FileReader.readAsText():返回文本,需要指定文本编码,默认为 UTF-8。
- FileReader.readAsArrayBuffer():返回 ArrayBuffer 对象。
- FileReader.readAsDataURL():返回 Data URL。
- FileReader.readAsBinaryString():返回原始的二进制字符串。
//FileReader.readAsText()方法的例子,用来读取文本文件。
// HTML 代码如下
// <input type=’file' onchange='readfile(this.files[0])'></input>
// <pre id='output'></pre>
function readfile(f) {
var reader = new FileReader()
reader.readAsText(f)
reader.onload = function() {
var text = reader.result
var out = document.getElementById('output')
out.innerHTML = ''
out.appendChild(document.createTextNode(text))
}
reader.onerror = function(e) {
console.log('Error', e)
}
}
//FileReader.readAsArrayBuffer()方法的例子,用于读取二进制文件。
// HTML 代码如下
// <input type="file" onchange="typefile(this.files[0])"></input>
function typefile(file) {
// 文件开头的四个字节,生成一个 Blob 对象
var slice = file.slice(0, 4)
var reader = new FileReader()
// 读取这四个字节
reader.readAsArrayBuffer(slice)
reader.onload = function(e) {
var buffer = reader.result
// 将这四个字节的内容,视作一个 32 位整数
var view = new DataView(buffer)
var magic = view.getUint32(0, false)
// 根据文件的前四个字节,判断它的类型
switch (magic) {
case 0x89504e47:
file.verified_type = 'image/png'
break
case 0x47494638:
file.verified_type = 'image/gif'
break
case 0x25504446:
file.verified_type = 'application/pdf'
break
case 0x504b0304:
file.verified_type = 'application/zip'
break
}
console.log(file.name, file.verified_type)
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 对象
File 对象代表一个文件,用来读写文件信息。它继承了 Blob 对象,或者说是一种特殊的 Blob 对象,所有可以使用 Blob 对象的场合都可以使用它。
最常见的使用场合是表单的文件上传控件(<input type="file">),用户选中文件以后,浏览器就会生成一个数组,里面是每一个用户选中的文件,它们都是 File 实例对象。
// HTML 代码如下
// <input id="fileItem" type="file">
var file = document.getElementById('fileItem').files[0]
file instanceof File // true file是用户选中的第一个文件,它是 File 的实例。
2
3
4
构造函数
浏览器原生提供一个 File()构造函数,用来生成 File 实例对象。
new File(array, name [, options])
2
- array:一个数组,成员可以是二进制对象或字符串,表示文件的内容。
- name:字符串,表示文件名或文件路径。
- options:配置对象,设置实例的属性。该参数可选。
第三个参数配置对象,可以设置两个属性。
- type:字符串,表示实例对象的 MIME 类型,默认值为空字符串。
- lastModified:时间戳,表示上次修改的时间,默认为 Date.now()。
从上图可以发现, File 对象有些实例属性和实例方法
- File.lastModified:最后修改时间
- File.name:文件名或文件路径
- File.size:文件大小(单位字节)
- File.type:文件的 MIME 类型
# FileList 对象
FileList 对象是一个类似数组的对象,代表一组选中的文件,每个成员都是一个 File 实例。它主要出现在两个场合。
文件控件节点(<input type="file">)的 files 属性,返回一个 FileList 实例。
拖拉一组文件时,目标区的 DataTransfer.files 属性,返回一个 FileList 实例。
// HTML 代码如下
// <input id="fileItem" type="file">
var files = document.getElementById('fileItem').files
files instanceof FileList // true
2
3
4
FileList 的实例属性主要是 length,表示包含多少个文件。
由于 FileList 的实例是一个类似数组的对象,可以直接用方括号运算符,即 myFileList[0]就是第一个 file 实例
# FileReader 对象
FileReader 对象用于读取 File 对象或 Blob 对象所包含的文件内容。
浏览器原生提供一个 FileReader 构造函数,用来生成 FileReader 实例。
var reader = new FileReader()
FileReader 有以下的实例属性。
- FileReader.error:读取文件时产生的错误对象
- FileReader.readyState:整数,表示读取文件时的当前状态。一共有三种可能的状态,0 表示尚未加载任何数据,1 表示数据正在加载,2 表示加载完成。
- FileReader.result:读取完成后的文件内容,有可能是字符串,也可能是一个 ArrayBuffer 实例。
- FileReader.onabort:abort 事件(用户终止读取操作)的监听函数。
- FileReader.onerror:error 事件(读取错误)的监听函数。
- FileReader.onload:load 事件(读取操作完成)的监听函数,通常在这个函数里面使用 result 属性,拿到文件内容。
- FileReader.onloadstart:loadstart 事件(读取操作开始)的监听函数。
- FileReader.onloadend:loadend 事件(读取操作结束)的监听函数。
- FileReader.onprogress:progress 事件(读取操作进行中)的监听函数。
监听 load 事件的一个例子:
// HTML 代码如下
// <input type="file" onchange="onChange(event)">
function onChange(event) {
var file = event.target.files[0]
var reader = new FileReader()
reader.onload = function(event) {
console.log(event.target.result)
}
reader.readAsText(file)
}
//每当文件控件发生变化,就尝试读取第一个文件。如果读取成功(load 事件发生),就打印出文件内容。
2
3
4
5
6
7
8
9
10
11
12
13
FileReader 有以下实例方法。
- FileReader.abort():终止读取操作,readyState 属性将变成 2。
- FileReader.readAsArrayBuffer():以 ArrayBuffer 的格式读取文件,读取完成后 result 属性将返回一个 ArrayBuffer 实例。
- FileReader.readAsBinaryString():读取完成后,result 属性将返回原始的二进制字符串。
- FileReader.readAsDataURL():读取完成后,result 属性将返回一个 Data URL 格式(Base64 编码)的字符串,代表文件内容。对于图片文件,这个字符串可以用于元素的 src 属性。注意,这个字符串不能直接进行 Base64 解码,必须把前缀 data:/;base64,从字符串里删除以后,再进行解码。
- FileReader.readAsText():读取完成后,result 属性将返回文件内容的文本字符串。该方法的第一个参数是代表文件的 Blob 实例,第二个参数是可选的,表示文本编码,默认为 UTF-8。
/* HTML 代码如下
<input type="file" onchange="previewFile()">
<img src="" height="200">
*/
function previewFile() {
var preview = document.querySelector('img')
var file = document.querySelector('input[type=file]').files[0]
var reader = new FileReader()
reader.addEventListener(
'load',
function() {
preview.src = reader.result
},
false
)
if (file) {
reader.readAsDataURL(file)
}
}
//用户选中图片文件以后,脚本会自动读取文件内容,然后作为一个 Data URL 赋值给<img>元素的src属性,从而把图片展示出来。
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23