重新认识 File API

微信扫一扫,分享到朋友圈

重新认识 File API

File & FileReader & FileList & Blob & URL scheme 这几个方法或者说是“接口”都是一同被定义在了 W3C File API 的规范之中。

如果要画一张关系图的话,按照理解应该是这样的:

Blob

最初被 Google 使用的时候叫做 Binary Large Object ,表示不可变的原始二进制数据

参数

new Blob(blobParts : Array, [blobPropertyBag : Object]) : Blob
blobPropertyBag : {
type	String	A valid mime type such as 'text/plain'
endings	String	Must be either 'transparent' or 'native'
}

Blob 第一个参数可以接受的数据类型有:

BufferSource
Blob
USVString

第二个参数可以接受

  • type 通常我们会传一些媒体类型,比如指定 mp3, png格式
  • endings 只能传 ‘transparent’ 或者 ‘native’
var blob = new Blob(['foo', 'bar']);
console.log('size=' + blob.size);
console.log('type=' + blob.type);
var testEndings = function(string, endings) {
var blob = new Blob([string], { type: 'plain/text',
endings: endings });
var reader = new FileReader();
reader.onload = function(event){
console.log(endings + ' of ' + JSON.stringify(string) +
' => ' + JSON.stringify(reader.result));
};
reader.readAsText(blob);
};
testEndings('foonbar',   'native');
testEndings('foornbar', 'native');
testEndings('foonbar',   'transparent');
testEndings('foornbar', 'transparent');
size=6
type=
native of "foonbar" => "foonbar"
native of "foornbar" => "foonbar"
transparent of "foonbar" => "foonbar"
transparent of "foornbar" => "foornbar"

属性:

  • type 只读属性
  • size 只读属性
var blob = new Blob(['foo', 'bar'], { type: 'plain/text',
endings: 'native' });
console.log(blob.type); // plain/text
var blob = new Blob(['foo', 'bar'], { type: 'plain/text',
endings: 'native' });
console.log(blob.size); // 6

方法

  • slice
  • stream
  • text
  • arrayBuffer

slice 顾名思义,和数组的 slice 差不多,传入起始位置 start 和终止位置 end,截取的内容是从 start ~ end – 1 区间的内容,如果传入负数和超过长度的值,则会根据具体的规则进行调整,不做赘述,可以看具体规范定义的。

var blob = new Blob(['foo', 'bar'], { type: 'plain/text',
endings: 'native' });
console.log('blob size:', blob.size); // blob size: 6
console.log('blob type:', blob.type); // blob type: plain/text
var copy = blob.slice()
console.log('copy size:', copy.size); // copy size: 6
console.log('copy type:', copy.type); // copy type:
var slice = blob.slice(1, 4, 'foo-type')
console.log('slice size:', slice.size); // slice size: 3
console.log('slice type:', slice.type); // slice type: foo-type

steam ,arrayBuffer,和 text 在兼容性上比较差,,steam 是用 ‘流’ 的方式返回,text 方法返回 promise, then 方法中可以拿到完整的 blob 内容。

var blob = new Blob(['abcd'])
blob.text().then(res => {
console.log(res) // abcd
})

兼容性:

File

File 对象继承自 Blob,并增加了几个属性用于描述该对象。

new File(fileParts : Array, name : String, [filePropertyBag : Object]) : File
filePropertyBag : {
type	String	A valid mime type such as 'text/plain'
endings	String	Must be either 'transparent' or 'native'
lastModified long
}

File 第一个参数可以接受的数据类型有:

BufferSource
Blob
USVString

第二参数:name, 指定文件名

第三参数: 接收一个对象, 比 Blob 多了一个字段, lastModified 用来指定修改时间。

构造一个 File 对象:

var d = new Date(2020, 08, 01, 16, 23, 45, 600);
var generatedFile = new File(["Rough Draft ...."], "Draft1.txt", {type: "text/plain", lastModified: d})

属性

  • name 只读
  • lastModified 只读

FileList

一个包含所有 File 文件集合的 list。可以通过在 file 标签上指定 multiple 来让用户可以多选文件。通过类似数组下标的方式获取对应的 File 对象。

<input id='file-input' type='file' multiple>
<script>
var fileInput = document.getElementById('file-input');
fileInput.addEventListener('change', function(event) {
var input = event.target;
for (var i = 0; i < input.files.length; i++) {
console.log(input.files[i].name);
}
});
</script>

FileReader

提供异步读取方法,可以通过事件监听的方式来异步的获取文件的数据,可以读取 File 和 Blob 对象的内容。

写了一个 Demo 用于读取本地文件,并展示读取进度条的例子:chestnut::

See the Pen file read progress by hjoker ( @hjoker ) on CodePen .

由于本质上是读取文件并加载到内存中,所以不推荐直接读取大文件,因为这样会导致浏览器占用过多内存,即便浏览器内部会适时的释放内存,但是依旧会碰到无响应的后果。

FileReader 有一个方法 readAsDataURL ,它可以自动帮你生成对应文件的 Base64 字符串,并在 onload 时候触发,可以从 result 属性中获取到。

再看一眼下面这张图是不是和 XMLHttpRequest 很类似?有 onload error 一系列方法。 同样需要注意,载入过大的文件尺寸会影响浏览器计算 Base64 的速度

See the Pen FileReader get Base64 by hjoker ( @hjoker ) on CodePen .

列一下 state 的几种状态。 初始状态是 Empty 也就是 0

var reader = new FileReader()
> reader.readyState
> FileReader.EMPTY
> FileReader.LOADING
1
> FileReader.DONE
2

See the Pen FileReader state by hjoker ( @hjoker ) on CodePen .

触发事件:

  • onloadstart
  • onprogress
  • onabort
  • onerror
  • onload
  • onloadend

方法:

  • readAsDataURL(blob) 转换为 Base64
  • readAsText(blob, encoding) // 如果是纯文本,可以拿到文本内容
  • readAsArrayBuffer(blob) 转成 ArrayBuffer
  • readAsBinaryString(blob)

参考出处:

曝郑爽发错货用13万项链补偿 郑爽闲鱼账号介绍

上一篇

Python 多进程之间共享变量

下一篇

你也可能喜欢

重新认识 File API

长按储存图像,分享给朋友