理解web文件操作的全过程(Blob, File, ArrayBuffer)

1,798 阅读4分钟

web应用提供能力去访问文件,与之对应的也提供了一组API去访问文件数据。

相关文件接口

  • ArrayBuffer: 表示通用的、固定长度的原始二进制数据缓冲区(无法操纵其内部的原始二进制数据)
  • Blob(binary large object):代表不可更改的原始二进制数据,并可以以字节的方式去访问blob对象
  • File:包含了文件的信息化属性,包括文件名称和最近修改时间等等,本身是blob的子类
  • FileList:基础文件系统被选择的独立文件数组,即File对象的数组
  • FileReader:提供方法去访问file和blob对象,并提供相应的事件机制去获取读操作的结果,以异步的方式进行,不阻碍UI渲染和JS执行。
  • URL scheme:用于文件等类型的二进制数据,使之可以在web应用中以引用(url 链接)方式访问

文件操作流程

image.png 文件操作基本方式:

  1. 用户使用input元素接口访问文件系统,获取由file对象组成的fileList文件列表。
  2. 通过fileReader对象访问file对象,fileReader提供相应方法和对应的事件模型监听文件读取。
  3. file对象基于Blob类型, 继承使用Blob的相应方法转化为Arraybuffer类型,也同样可以转化为url引用,以链接的方式访问
  4. xhr.send()方法支持blob和arrayBuffer格式, 故file对象可以作为send方法参数传入,将文件上传至服务器

重要接口介绍

  • Blob 不可变、原始数据的类文件对象

    个人理解 Blob不同于ArrayBuffer只表示二进制数据,还暴露了在宏观上处理二进制数据的方法

    1.Blob.text() 映射为utf-8的字符串(utf-8是一种编码规范,相当于数值和字符之间的映射关系,其中“8”代表编码最少一字节,可兼容ASCII编码)

    2.Blob.arrayBuffer() 转换为二进制数据的arrayBuffer

  • fileReader 异步读取file或者blob对象所指代的文件或数据

    相比于blob使用本身的方法转化为其他格式的数据,fileReader方法提供了更多的格式选择和流程控制以及更好的 兼容性(支持IE)

深入二进制的世界

众所周知,计算机是二进制的世界,任何一个字符都只是二进制数字的映射表达,例如ASCII编码 ‘A’以二进制格式表示:ob10000001,而我们所见的十进制数值同理存储时也是用二进制的方式。

上述的blob对象虽可以宏观上处理二进制数据(比如说格式转化和slice切割),但并不能处理其内部真正的二进制数据(例如访问和赋值),而arrayBuffer虽表示原始且固定的二进制数据,但不能操作其内容,那arrayBuffer的作用是什么呢?

javascript引入了类型化数组的概念,提供了访问原始二进制内容的能力,类型化数组是类数组对象,类似于NodeList,arguments等等。 类型化数组为了提高灵活性和扩展性,将访问二进制的实现拆分为缓冲和视图。缓冲即arrayBuffer,定义你想要的存储空间,而视图(即TypedArray)提供对缓冲的访问。

以下是类型化数组对缓冲的访问拆分

注: 类型化数组是一类构造函数的总称,构造函数的名称表达视图在缓冲上的分拆规则,例如 构造函数UInt32Array 其中的'32'代表每个元素占32bit(4byte),故缓冲区以4byte单位进行视图划分

image.png

下面我们使用类型化数组实现一下简单的二进制访问

   // 先创建一个ArrayBuffer实例,并分配32字节的空间
   const buffer = new ArrayBuffer(32)
   // 看一下二进制缓存大小
   console.log(buffer.byteLength)  // 32 
   // 建立基于buffer的视图 (每个数组元素占32bit(=4byte),Int代表整数类型),所以数组共8个元素
   const view = new Int32Array(buffer)
   // 访问二进制内部
   for (let index = 0; index < view.length; index++) {
     view[index] = index + 1
   }
   // 看看结果怎么样
   console.log(Array.prototype.join.call(view,'')) // 12345678
   

这是类型化数组的简单介绍,具体可以看MDN文档ECMA规范