在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 // 1517414400000
myFile.name // "file.bin"
myFile.size // 0
myFile.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 />![image.png](https://cdn.nlark.com/yuque/0/2022/png/737887/1647096568708-f68c7b87-4d68-4b92-bc68-fdf469a02827.png#clientId=u2bf720c1-110f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=86&id=uea44b73f&margin=%5Bobject%20Object%5D&name=image.png&originHeight=132&originWidth=412&originalType=binary&ratio=1&rotation=0&showTitle=false&size=11512&status=done&style=none&taskId=udfc23c86-61bc-45bc-893e-869640cb24e&title=&width=269)<br />**读取到png图片**<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/737887/1647096595833-deb9a878-d981-45d8-befd-f0731caa4f66.png#clientId=u2bf720c1-110f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=266&id=ubf9d0a96&margin=%5Bobject%20Object%5D&name=image.png&originHeight=532&originWidth=1218&originalType=binary&ratio=1&rotation=0&showTitle=false&size=193906&status=done&style=none&taskId=u036fccf5-48e4-4c56-aad6-8f2c564f99c&title=&width=609)<br />readAsText读取文件的单位是字符,故对于文本文件,只要按规定的编码方式读取即可;<br />而对于媒体文件(图片、音频、视频),其内部组成并不是按字符排列,故采用readAsText读取,会产生乱码。
<a name="kNBZn"></a>
#### BinaryString类型
```javascript
// HTML 代码如下
<input type="file" id="file"></input>
// javascript
var input = document.getElementById("file"); //input file
input.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>
// JavaScript
var input = document.getElementById("file"); //input file
input.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>
// JavaScript
let input = document.getElementById("file"); //input file
input.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>
// JavaScript
let input = document.getElementById("file"); //input file
input.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>
// javascript
var input = document.getElementById("file"); // input file
input.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){
// 响应成功
}
}
}
}