javascript filereader,前端filereader
写在前面
上一篇文章介绍了HTML5中的Blob对象(详情戳此处),了解到Blob对象只是二进制数据的容器,本身并不能操作二进制,所以本文将介绍其操作对象FileReader。
FileReader
FileReader主要用于将文件的内容读入内存。通过一系列异步接口,可以在主线程中访问本地文件。
使用FileReader对象,web应用程序可以异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,并可以使用File对象或Blob对象来指定要处理的文件或数据。
创建实例
var reader=new FileReader();方法
方法定义描述abort():void终止文件读取操作readAsArrayBuffer(file):void异步按字节读取文件内容,结果由ArrayBuffer对象表示为readasbinarystring(file):void异步按字节读取文件内容,结果文件的二进制字符串ReadasDataURL (file,encoding): void异步读取文件内容,结果表示为字符串data:url。Void按字符异步读取文件内容,结果用字符串表示。
事件
事件描述onabort在读操作中止时调用onerror,在读操作有错误时调用onload,在读操作成功完成时调用onloadend,在读操作完成时调用onloadstart,无论成功还是失败。在读取数据的过程中,会定期调用onprogress。
使用方法
FileReader异步读取文件内容,结果都是通过事件回调得到的。下面是一个读取本地txt文件内容的示例:
var input=document . getelementbyid( file );//input file input . onchange=function(){ var file=this . files[0];如果(!File){ //读取本地文件,以gbk编码输出var reader=new file reader();reader.readAsText(文件, gbk );Reader.onload=function(){ //读取后输出结果console . log(this . result);}}}另外,我们可以通过注册onprogress、onerror等事件来记录文件读取进度或异常行为。
读取方式
FileReader提供了四种不同的读取文件的方式,比如:readAsArrayBuffer将文件的内容作为ArrayBuffer对象读取,readAsBinaryString将文件作为二进制字符串读取。下面简单区分四种方式。
首先准备一张图片(6764字节)和一个txt文本(51字节)作为测试文件:
然后编写测试代码:
var reader=new FileReader();//四种方式读取文件///reader . readas XXX(file);Reader.onload=function(){ //检查文件输出内容console . log(this . result);//检查文件内容字节大小console . log(new blob([this . result])}readAsDataURL
查看图像输出结果:
参见txt输出结果:
很明显,readAsDataURL会输出base64编码后的文件内容,很容易区分。
readAsText
这个方法可以通过不同的编码方式读取字符,我们使用utf-8来读取。
查看图像输出结果:
参见txt输出结果:
readAsText读取文件的单位是字符,所以对于文本文件,只需要按照规定的编码方式读取即可;
但是对于媒体文件(图片、音频、视频),其内部组件并不是按照字符排列的,所以使用readAsText读取会产生乱码,并不是理想的读取文件方式。
readAsBinaryString
查看图像输出结果:
参见txt输出结果:
与readAsText不同,readAsBinaryString函数以字节为单位读取文件内容。
但是0101这样的二进制数据只能被机器识别。如果它想对外界可见,还是需要编码一次,readAsBinaryString的结果就是读取二进制和编码后的内容。
虽然readAsBinaryString方法可以按字节读取文件,但它不适合直接传输,不推荐使用,因为读取的内容被编码为字符,大小会受到影响。
例如,测试的图片文件的原始大小是6764字节,但是在被readAsBinaryString读取后,内容被扩展到10092字节。
readAsArrayBuffer
查看图像输出结果:
参见txt输出结果:
与readAsBinaryString类似,readAsArrayBuffer方法以字节为单位读取文件内容,并将其转换为ArrayBuffer对象。
我们可以在阅读后关注文件的大小,与原文件大小一致。
这就是readAsArrayBuffer和readAsBinaryString方法的区别。readAsArrayBuffer读取一个文件后,会在内存中创建一个ArrayBuffer对象(二进制缓冲区),并在其中存储二进制数据。这样,我们就可以直接在网络中传输二进制内容。
毕竟,ArrayBuffer到底是什么?
ArrayBuffer对象涉及的知识点很多,可以在单篇文章中详细讲解。这里可以简单理解为存储一段二进制数据的内存空间。
但是ArrayBuffer中的内容本身对外界是不可见的,所以要查看内容,还要引入另一个概念:类型化数组。
我们可以尝试用readAsArrayBuffer方法来检查刚刚读取的图片文件的内容:
可以看到,整个图片文件的6764个字节存储在一个长度为6764的数组中,数组中每个元素的值就是当前字节的十进制值。
这里不深入解释ArrayBuffer和类型化数组的概念,后面会写一个单独的讨论。
应用场景
说了这么多,最终还是要实现FileReader能解决什么问题。这里有一些例子来说明:
在线预览本地文件
我们知道,可以将img的src属性或背景的url属性赋给图像网络地址或base64来显示图像。
在文件上传中,我们通常先上传本地文件到服务器。上传成功后,后台返回的图片的网络地址会显示在前端。
通过FileReader的readAsDataURL方法,我们可以直接在页面上显示本地图片,而不需要经过后台。这样做可以减少前后端频繁的交互过程,减少服务器端无用的图片资源。代码如下:
var input=document . getelementbyid( file );//input file input . onchange=function(){ var file=this . files[0];如果(!file){ var reader=new FileReader();//图像文件转换成base64Reader.readasDataURL(文件);Reader.onload=function(){ //显示图片document . getelementbyid( file _ img )。src=this.result}}}运行效果如下:
对于图片上传,我们也可以先把图片转换成base64进行传输。此时,由于传输的图像内容是一个字符串,上传接口可以作为一个普通的post接口。图像传输到后台后,可以转换成文件实体进行存储。
当然,考虑到base64的转换效率和自身大小,这种方式还是适合上传内容简单或者内存小的文件。
二进制数据上传
HTML5系统的建立引入了很多新的东西。基于XHR2,我们可以直接上传或下载二进制内容,而不用像以前那样通过form标签从后端拉取二进制内容。
简单梳理一下上传逻辑:
1.通过input[type=file]标签获取本地文件的File对象。
2.通过FileReader的readAsArrayBuffer方法将File对象转换为ArrayBuffer。
3.创建xhr对象并配置请求信息。
4.通过xhr.sendAsBinary将文件的ArrayBuffer内容直接填充到post体中并发送。
代码实现如下:
var input=document . getelementbyid( file );//input file input . onchange=function(){ var file=this . files[0];如果(!file){ var reader=new FileReader();reader.readAsArrayBuffer(文件);reader . onload=function(){ var binary=this . result;上传(二进制);} } }//文件上传函数upload(binary){ var xhr=newxmlhttprequest();xhr.open(POST , http://xxxx/op load );xhr . override imetype( application/octet-stream );//直接发送二进制数据if(xhr . sendas binary){ xhr . sendas binary(binary);} else { xhr . send(binary);}//监听更改xhr . onreadystatechange=function(e){ if(xhr . ready state==4){ if(xhr . status==200){//响应成功}}}总结
本文主要介绍FileReader对象的属性和应用场景。使用FileReader,我们可以将本地文件读入内存。在本文中,我们提到了ArrayBuffer和typed array的概念,它们使我们能够进一步操作内存中的二进制数据。这一部分将在下面的博客中进行总结。
参考数据
[1] MDN_FileReader
Unicode和UTF-8有什么区别?
关于HTML5 FileReader对象的具体用法的这篇文章就到这里了。有关HTML5 FileReader对象的更多信息,请搜索以前的文章或继续浏览下面的相关文章。希望你以后能支持我!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。