File、Blob、ArrayBuffer等文件类的对象有什么区别和联系
前言
在前端中处理文件时会经常遇到File、Blob、ArrayBuffer以及相关的处理方法或方式如FileReader、FormData等等这些名词,对于这些常见而又不常见的名词,我相信大多数人对它们都有一种熟悉的陌生人的感觉。究其原因,相关的东西接触的不够多,且每次都网上随手拈来,不求甚解。今天,我们就稍微仔细一点,去做一个探究,弄清他们是谁,能做什么,又有什么区别,争取下次再见既是“老朋友”。如果,你想更深入的了解相关知识点,可以参阅w3c和MDN的解释,文后会附上相关的参考链接供参考。
内容
File
定义/概念
File即我们通常所说的文件,我们硬盘里存储的音视频、文档等等都是文件。我们通常使用<input type="file">
来选取并读取本地计算机中的文件,返回一个Filelist对象,此对象为一个类数组可迭代对象。File对象是特殊类型的Blob,所以顺便也继承了Blob特有的方法和属性,同时又有自己独特的属性和方法。
MDN定义:文件(
File
)接口提供有关文件的信息,并允许网页中的 JavaScript 访问其内容。通常情况下,File
对象是来自用户在一个<input>
元素上选择文件后返回的FileList
对象,也可以是来自由拖放操作生成的DataTransfer
对象,或者来自HTMLCanvasElement
上的mozGetAsFile
() API。
用法/示例
File常用的属性有:
File.name
只读,返回当前File 对象所引用文件的名称。
File.size
只读,返回当前File 对象文件的大小。
File.type
只读,返回文件的多用途互联网邮件扩展类型(MIME Type)
更多属性及方法信息可参考MDN,这里就不再详细赘述。
FileList: <input type="file">
元素有一个files属性,用来存储用户所选择的文件,当用户点击选择文件按钮之后,便可以获取到选择的文件组成的FileList对象。
1 |
const fileList = document.getElementById('file').files; |
在这几个当中,File应该是我们使用的频率最高的一个,应该也是最熟悉的一个,所以过多的内容这里就不一一示例。这里引入一个很久之前遇到的一个相关的IE兼容性问题。
input[type=file]这个文件上传原生按钮不够美观,通常都是采取隐藏此原生的按钮,使用另外一个自定义的按钮,然后,通过点击此按钮间接触发隐藏的原生按钮,从而实现这一功能。但是,由于IE安全限制,我们间接通过clik()触发的,在IE9某些版本就会报SCRIPT: 拒绝访问
的错误。解决这个问题,要主动触发上传按钮,此时借助label的for属性,绑定到对应的input上即可解决此问题。
Blob
定义/概念
Blob是Binary Large Object
的缩写,表示二进制大对象,它并不是前端的所特有对象,而是计算机界的通用术语,在一些数据库中,例如,MYSQL中的BLOB类型就表示二进制数据的容器。MDN上对其的定义是:Blob
对象表示一个不可变、原始数据的类文件对象。可以通俗的说,Blob就是一只读的二进制对象。从File的介绍我们已知File继承自Blob,有许多相同的方法和属性,因此可以像操作File对象一样操作Blob对象。
用法/示例
Blob主要包含两个属性
Blob.size
:只读,对象中所包含数据的大小(字节)Blob.type
:只读,一个字符串,表明该Blob
对象所包含数据的 MIME 类型。如果类型未知,则该值为空字符串。(MIME类型参考)
创建一个Blob对象,需要调用Blob构造函数。
1 |
/** |
array 是一个由
ArrayBuffer
,ArrayBufferView
,Blob
,DOMString
等对象构成的Array
,或者其他类似对象的混合体,它将会被放进Blob
。DOMStrings
会被编码为UTF-8。options 是一个可选的
BlobPropertyBag
字典,它可能会指定如下两个属性:
type
,默认值为""
,它代表了将会被放入到blob中的数组内容的MIME类型。endings
,默认值为"transparent"
,用于指定包含行结束符\n
的字符串如何被写入。 它是以下两个值中的一个:"native"
,代表行结束符会被更改为适合宿主操作系统文件系统的换行符,或者"transparent"
,代表会保持blob中保存的结束符不变
使用示例:
1 |
const data1 = "a"; |
以上blob5的size值打印为什么是15呢?原因是,当使用普通对象创建Blob对象时,相当于调用了普通对象的toString()
方法得到字符串数据,然后再创建Blob对象。所以,blob5保存的数据是"[object Object]"
,是15个字节(不包含最外层的引号)。
Blob目前有四个方法:
Blob.slice([start[, end[, contentType]]])
:返回一个新的 Blob
对象,包含了源 Blob
对象中指定范围内的数据。(由于File继承自Blob,可用此方法分割本地文件,实现分片上传)
Blob.stream()
:返回一个能读取blob内容的 ReadableStream
。
Blob.text()
:返回一个promise且包含blob所有内容的UTF-8格式的 USVString
。
Blob.arrayBuffer()
:返回一个promise且包含blob所有内容的二进制格式的 ArrayBuffer
ArrayBuffer
定义/概念
你从XHR、File API、Canvas等等各种地方,读取了一大串字节流,如果用JS里的Array去存,又浪费,又低效。
于是为了配合这些新的API增强JS的二进制处理能力,就有了ArrayBuffer。
ArrayBuffer
简单说就是一片内存,表示原始二进制数据缓冲区。但不能直接操作它,而是要通过类型数组对象TypedArray
或 DataView
(数据视图)对象来操作它,它们会将缓冲区中的数据表示为特定的格式,并通过这些格式来读写缓冲区的内容。TypedArray
给ArrayBuffer
提供了一个“View
”,对它们进行下标读写。也可以使用DataView来读写ArrayBuffer
,DataView
能更自由的选择字节序,不用考虑不同平台的字节序问题。
MDN将
ArrayBuffer
对象定义为用来表示通用的、固定长度的原始二进制数据缓冲区。它是一个字节数组,通常在其他语言中称为“byte array”。
用法示例
由于ArrayBuffer
不能直接进行操作,故需要借助TypedArray
或者DataView
来进行读写。
1 |
// 生成一个可以16个字节的连续内存,每个字节的默认值是0 |
结语
区别/联系
File和Blob
相同点: File和Blob都可以用来表示类文件对象,处理文件;
FIle: File可以看作一个承载文件的桥梁,将DOM接口和文件联系起来,通过File这个桥梁,获取计算及内的文件,从而对才能对文件做进一步处理。
Blob:File继承自Blob,他们之间很方便进行转换,Blob是File都原型对象。
联系:File继承自Blob,同时又有自己独特的属性和方法。从下面的打印可以看出,其实Blob对象就是File的原型对象,自然就拥有了Blob对象的方法和属性。
1
<input type="file" id="myfiles" />
1
2
3
4
5
6
7const fileDOM = document.querySelector("#myfiles");
const fileChange = (e) => {
const files = fileDOM.files;
console.log(files[0].__proto__) // 输出File
console.log(files[0].__proto__.__proto__) // 输出Blob
}
fileDOM.onchange = fileChange;
Blob与ArrayBuffer
相同点:
Blob
和ArrayBuffer
都是二进制的容器。ArrayBuffer:
ArrayBuffer
更底层,是一段纯粹的内存上的二进制数据,我们可以对其任何一个字节进行单独的修改,也可以根据我们的需要以我们指定的形式读取指定范围的数据。Blob:
Blob
就是将二进制数据做了一个封装,我们拿到的就是一个整体,可以看到它的整体属性大小、类型;可以对其分割,但看不到它内部的细节联系:
Blob
可以接受一个ArrayBuffer
作为参数生成一个Blob
对象,此行为就相当于对ArrayBuffer
数据做一个封装。应用上的区别:由于
ArrayBuffer
和Blob
的特性,Blob
作为一个整体文件,适合用于文件传输;而只有需要关注细节(比如要修改某一段数据时),此时使用ArrayBuffer
比较好。
从以上我们的介绍以及联系,我们可以得出如下的转换函数
1 |
/** |
1 |
/** |
弄清了他们之间的关系,在以后的工作学习中,才能刚好的去使用这些对象,让其用在最适用的地方。而不是每次都一头雾水,熟悉并陌生着。对于和他们相关的FileReader、Base64、FormData,后续会更新相关内容,将其进行联系起来,更好的理解他们。
参考资料
- MDN Web API 接口参考 - File
- MDN Web API 接口参考 - Blob
- JavaScript 标准内置对象 - ArrayBuffer
- Blob、ArrayBuffer、File、FileReader和FormData的区别
- 细说Web API中的Blob
File、Blob、ArrayBuffer等文件类的对象有什么区别和联系的更多相关文章
- [转]DataURL与File,Blob,canvas对象之间的互相转换的Javascript
来源 http://blog.csdn.net/cuixiping/article/details/45932793 canvas转换为dataURL (从canvas获取dataURL) var d ...
- DataURL与File,Blob,canvas对象之间的互相转换的Javascript
canvas转换为dataURL (从canvas获取dataURL) var dataurl = canvas.toDataURL('image/png'); var dataurl2 = canv ...
- scala快速学习笔记(二):控制结构,类和对象
IV.控制结构 1.if/else 除基本用法外,if/else语句能用来赋值,进而代替?:运算符.这得益于在Scala中,每个语句块都有值,就是该语句块最后一个语句的值.请看下面的代码. def a ...
- Java学习——类与对象
在学习面向对象之前首先我们要理解一下几点: 什么是面向对象 对象的概念 类 类与对象的关系/区别 什么是对象的属性 什么是对象的方法 什么是面向对象.对象.类 讲到面向对象就不得提到面向过程,早期的计 ...
- 下面的程序段创建了BufferedReader类的对象in,以便读取本机c盘my文件夹下的文件1.txt。File构造函数中正确的路径和文件名的表示是( )。
下面的程序段创建了BufferedReader类的对象in,以便读取本机c盘my文件夹下的文件1.txt.File构造函数中正确的路径和文件名的表示是( ). ./表示当前项目的路径../表示当 ...
- 孤荷凌寒自学python第三十四天python的文件操作对file类的对象学习
孤荷凌寒自学python第三十四天python的文件操作对file类的对象学习 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 一.close() 当一个file对象执行此方法时,将关闭当前 ...
- 理解DOMSTRING、DOCUMENT、FORMDATA、BLOB、FILE、ARRAYBUFFER数据类型
一.XMLHttpRequest 2.0的家臣们 我大学那会儿,一个称为Ajax的东西对前端行业造成了深远影响,不仅是JS语言,而包括前端地位.职位兴起以及工作分工等.抛开IE6浏览器不谈,其他浏览器 ...
- [原创]java WEB学习笔记77:Hibernate学习之路---Hibernate 版本 helloword 与 解析,.环境搭建,hibernate.cfg.xml文件及参数说明,持久化类,对象-关系映射文件.hbm.xml,Hibernate API (Configuration 类,SessionFactory 接口,Session 接口,Transaction(事务))
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- 文件类File
文件类File继承结构: public class File extends Object implements Serializable, Comparable<File> 常用方法: ...
随机推荐
- 【新阁教育】基于Log4Net实现日志信息双向存储(含源码)
1.引言 在上位机开发中,日志记录是必不可少的,我们可以通过日志记录做日志分析及错误追踪.初学者会采用txt文本写入来实现日志保存,但是文本写入不是线程安全,当存在多个线程同时写入日志时,就会出现一些 ...
- Javaweb应用中配置错误跳转页面
关于在Javaweb应用中配置错误跳转页面 应用场景,比如服务器的出现404错误,我们想让它返回跳转到我们自定义的错误页面 解决方法: 主要在web.xml文件中进行配置,这里玩的错误页面都单独放在e ...
- Python远程连接Redis
import redisr=redis.Redis(host='192.168.56.102',port=6379,db=0,password='jinxfredis' )r.set('name',' ...
- 使用 usbmon 抓取 usb 总线上的数据
使用 usbmon 抓取 usb 总线上的数据 usbmon 即 usb monitor,是 linux 内置的 usb 抓包工具.usbmon 本质是一个内核模块,在我的 ubuntu14.0 4中 ...
- 微信小程序入门到精通
微信小程序账号与工具 在线文档:https://mp.weixin.qq.com/debug/wxadoc/dev/ 小程序开发者账号注册 微信公众平台:https://mp.weixin.qq.co ...
- SpringMVC初始化阶段流程源码分析
1.都知道SpringMVC项目启动的时候都会初始化一个类:DispatcherServlet,看这个类的源码我们可以发现他其实就是一个servlet, 为什么这么说呢?请看: DispatcherS ...
- Flutter学习六之实现一个带筛选的列表页面
上期实现了一个网络轮播图的效果,自定义了一个轮播图组件,继承自StatefulWidget,我们知道Flutter中并没有像Android中activity的概念.页面见的跳转是通过路由从一个全屏组件 ...
- 获取NX一组属性
NX中的属性是可以分组的,有时我们想获取某一个组下的所有属性,但是NX封装的接口不够好用,因此在此基础上,我封装了一个,供大家参考: 1 //属性值是字符串类型,obj对象tag,category组名 ...
- jpeg编解码概述
本博文为概览性介绍.后面有空了再分几篇博文分别介绍所用到的技术细节. 1.编解码目标 编码和解码是个逆过程.jpeg编码的目的在于图形去冗余,进行数据压缩,解码的目的在于还原图像,使能够进行预览. 2 ...
- MySQL存储引擎入门介绍
什么是MySQL? MySQL 是一种关系型数据库,在Java企业级开发中非常常用,因为 MySQL 是开源免费的,并且方便扩展.阿里巴巴数据库系统也大量用到了 MySQL,因此它的稳定性是有保障的. ...