在Blob对象中提到读取Blob对象时,可以使用FileReader对象。本篇文件详细介绍关于File的使用
HTML5中的Blob对象只是二进制数据的容器,本身并不能操作二进制。
File 对象代表一个文件,用来读写文件信息。它继承了 Blob 对象,或者说是一种特殊的 Blob 对象,所有可以使用 Blob 对象的场合都可以使用它。
File对象
File()构造函数接受三个参数。
- array:一个数组,成员可以是二进制对象或字符串,表示文件的内容。
- name:字符串,表示文件名或文件路径。
- options:配置对象,设置实例的属性。该参数可选。
第三个参数配置对象,可以设置两个属性。
- type:字符串,表示实例对象的 MIME 类型,默认值为空字符串。
lastModified:时间戳,表示上次修改的时间,默认为Date.now()。
let file = new File(['foo'],'foo.txt',{type: 'text/plain',});
File 对象有以下实例属性。
File.lastModified:最后修改时间
- File.name:文件名或文件路径
- File.size:文件大小(单位字节)
- File.type:文件的 MIME 类型
由于myFile的内容为空,也没有设置 MIME 类型,所以size属性等于0,type属性等于空字符串。var myFile = new File([], 'file.bin', {lastModified: new Date(2018, 1, 1),});myFile.lastModified // 1517414400000myFile.name // "file.bin"myFile.size // 0myFile.type // ""
File 对象没有自己的实例方法,由于继承了 Blob 对象,因此可以使用 Blob 的实例方法slice()。FileReader对象
FileReader主要用于将文件内容读入内存,通过一系列异步接口,可以在主线程中访问本地文件。
FileReader 对象用于读取 File 对象或 Blob 对象所包含的文件内容。
浏览器原生提供FileReader构造函数,用来生成 FileReader 实例。
let reader = new FileReader();
FileReader对象的方法
| 方法定义 | 描述 |
|---|---|
| abort():void | 终止文件读取操作 |
| readAsArrayBuffer(file):void | 异步按字节读取文件内容,结果用ArrayBuffer对象表示 |
| readAsBinaryString(file):void | 异步按字节读取文件内容,结果为文件的二进制串 |
| readAsDataURL(file):void | 异步读取文件内容,结果用data:url的字符串形式表示 |
| readAsText(file,encoding):void | 异步按字符读取文件内容,结果用字符串形式表示 |
FileReader对象实例的属性
| 事件名称 | 描述 |
|---|---|
| error | 读取文件时产生的错误对象 |
| readyState | 表示读取文件时的当前状态,一共有三种可能的状态,0表示尚未加载任何数据,1表示数据正在加载,2表示加载完成。 |
| result | 读取完成后的文件内容,有可能是字符串,也可能是一个 ArrayBuffer 实例。 |
| onabort | 当读取操作被中止时调用 |
| onerror | 当读取操作发生错误时调用 |
| onload | 当读取操作成功完成时调用 |
| onloadend | 当读取操作完成时调用,不管是成功还是失败 |
| onloadstart | 当读取操作将要开始之前调用 |
| onprogress | 在读取数据过程中周期性调用 |
FileReader 使用
FileReader提供了四种不同的读取文件的方式:
- FileReader.readAsText():返回文本,需要指定文本编码,默认为 UTF-8。
- FileReader.readAsArrayBuffer():返回 ArrayBuffer 对象。
- FileReader.readAsDataURL():返回 Data URL。
- FileReader.readAsBinaryString():返回原始的二进制字符串。
text类型内容
```javascript // HTML 代码如下
// javascript var input = document.getElementById(“file”); //input file input.onchange = function(){ var file = this.files[0]; if(!!file){ //读取本地文件,以utf-8编码方式输出 var reader = new FileReader(); reader.readAsText(file,”utf-8”); reader.onload = function(){ //查看文件输出内容 console.log(this.result); //查看文件内容字节大小 console.log(new Blob([this.result])) } } }
读取到text类型文件,并显示到页面。通过注册onprogress、onerror等事件,记录文件读取进度或异常行为等等。<br />**读取的txt文件**<br /><br />**读取到png图片**<br /><br />readAsText读取文件的单位是字符,故对于文本文件,只要按规定的编码方式读取即可;<br />而对于媒体文件(图片、音频、视频),其内部组成并不是按字符排列,故采用readAsText读取,会产生乱码。<a name="kNBZn"></a>#### BinaryString类型```javascript// HTML 代码如下<input type="file" id="file"></input>// javascriptvar input = document.getElementById("file"); //input fileinput.onchange = function(){var file = this.files[0];if(!!file){//读取本地文件,以gbk编码方式输出var reader = new FileReader();reader.readAsBinaryString(file);reader.onload = function(){//查看文件输出内容console.log(this.result);//查看文件内容字节大小console.log(new Blob([this.result]))}}}
读取文本
读取图片
readAsBinaryString,会让数据变大
ArrayBuffer类型
// HTML 代码如下<input type="file" id="file"></input>// JavaScriptvar input = document.getElementById("file"); //input fileinput.onchange = function(){var file = this.files[0];if(!!file){//读取本地文件,以gbk编码方式输出var reader = new FileReader();reader.readAsArrayBuffer(file);reader.onload = function(){//查看文件输出内容console.log(this.result);//查看文件内容字节大小console.log(new Blob([this.result]))}}}
读取到文本
读取到图片打印的数据
与readAsBinaryString类似,readAsArrayBuffer方法会按字节读取文件内容,并转换为ArrayBuffer对象。
DataURL类型
// HTML 代码如下<input type="file" id="file"></input>// JavaScriptlet input = document.getElementById("file"); //input fileinput.onchange = function(){var file = this.files[0];if(!!file){//读取本地文件,以gbk编码方式输出var reader = new FileReader();reader.readAsDataURL(file);reader.onload = function(){//查看文件输出内容console.log(this.result);//查看文件内容字节大小console.log(new Blob([this.result]))}}}
项目中实际应用
在线预览本地文件
img的src属性或background的url属性,可以通过被赋值为图片网络地址或base64的方式显示图片。
在文件上传中,我们一般会先将本地文件上传到服务器,上传成功后,由后台返回图片的网络地址再在前端显示。
通过FileReader的readAsDataURL方法,可以不经过后台,直接将本地图片显示在页面上。这样做可以减少前后端频繁的交互过程,减少服务器端无用的图片资源,
// HTML 代码如下<input type="file" id="file"></input><img id="file_img"></img>// JavaScriptlet input = document.getElementById("file"); //input fileinput.onchange = function(){var file = this.files[0];if(!!file){//读取本地文件,以gbk编码方式输出var reader = new FileReader();reader.readAsDataURL(file);reader.onload = function(){//查看文件输出内容console.log(this.result);//查看文件内容字节大小console.log(new Blob([this.result]))// 显示图片document.getElementById("file_img").src = this.result;}}}
对于图片上传,也可以先将图片转换为base64进行传输,此时由于传输的图片内容是一段字符串,上传接口可以当做普通post接口处理,当图片传输到后台后,可以在转换为文件实体存储。
考虑到base64转换效率及其本身的大小,会使数据量增多1/3,本方法还是适合于上传内容简单或所占内存较小的文件。
二进制数据上传
比如日常开发中上传excel或者word文档等。
HTML5体系的建立引入了一大堆新的东西,基于XHR2,我们可以直接上传或下载二进制内容,无需像以往一样通过form标签由后端拉取二进制内容。
简单整理下上传逻辑:
1、通过input[type=”file”]标签获取本地文件File对象
2、通过FileReader的readAsArrayBuffer方法将File对象转换为ArrayBuffer
3、创建xhr对象,配置请求信息
4、通过xhr.sendAsBinary直接将文件的ArrayBuffer内容装填至post body后发送
// html<div id="file"></div>// javascriptvar input = document.getElementById("file"); // input fileinput.onchange = function(){var file = this.files[0];if(!!file){var reader = new FileReader();reader.readAsArrayBuffer(file);reader.onload = function(){var binary = this.result;upload(binary);}}}//文件上传function upload(binary){var xhr = new XMLHttpRequest();xhr.open("POST", "http://xxxx/opload");xhr.overrideMimeType("application/octet-stream");//直接发送二进制数据if(xhr.sendAsBinary){xhr.sendAsBinary(binary);}else{xhr.send(binary);}// 监听变化xhr.onreadystatechange = function(e){if(xhr.readyState===4){if(xhr.status===200){// 响应成功}}}}

