前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >重新认识 File API

重新认识 File API

作者头像
上山打老虎了
发布2022-06-15 08:44:27
4770
发布2022-06-15 08:44:27
举报
文章被收录于专栏:Article

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

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

Blob

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

参数

代码语言:javascript
复制
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 第一个参数可以接受的数据类型有:

第二个参数可以接受

  • type 通常我们会传一些媒体类型,比如指定 mp3, png格式
  • endings 只能传 ‘transparent’ 或者 ‘native’
代码语言:javascript
复制
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('foo\nbar',   'native');
testEndings('foo\r\nbar', 'native');
testEndings('foo\nbar',   'transparent');
testEndings('foo\r\nbar', 'transparent');



size=6
type=
native of "foo\nbar" => "foo\nbar"
native of "foo\r\nbar" => "foo\nbar"
transparent of "foo\nbar" => "foo\nbar"
transparent of "foo\r\nbar" => "foo\r\nbar"

属性:

  • type 只读属性
  • size 只读属性
代码语言:javascript
复制
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 区间的内容,如果传入负数和超过长度的值,则会根据具体的规则进行调整,不做赘述,可以看具体规范定义的。

代码语言:javascript
复制
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 内容。

代码语言:javascript
复制
var blob = new Blob(['abcd'])
blob.text().then(res => {
    console.log(res) // abcd
})

兼容性:

File

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

代码语言:javascript
复制
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 第一个参数可以接受的数据类型有:

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

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

构造一个 File 对象:

代码语言:javascript
复制
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 对象。

代码语言:javascript
复制
<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 用于读取本地文件,并展示读取进度条的例子🌰:

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。

代码语言:javascript
复制
var reader = new FileReader()
> reader.readyState
0
> FileReader.EMPTY
0
> FileReader.LOADING
1
> FileReader.DONE
2

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

触发事件:

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

方法:

  • readAsBinaryString(blob)
  • readAsArrayBuffer(blob) —— 将数据读取为二进制格式的 ArrayBuffer
  • readAsText(blob, [encoding]) —— 将数据读取为给定编码(默认为 utf-8 编码)的文本字符串。
  • readAsDataURL(blob) —— 读取二进制数据,并将其编码为 base64 的 data url

参考出处:

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020年08月02日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Blob
    • 参数
      • 属性:
        • 方法
        • File
          • 属性
          • FileList
          • FileReader
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档