HTML5 FileReader对象的具体使用方法


Posted in HTML / CSS onMay 22, 2020

写在前面

前一篇文章介绍了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):void 异步读取文件内容,结果用data:url的字符串形式表示
readAsText(file,encoding):void 异步按字符读取文件内容,结果用字符串形式表示

事件

事件名称 描述
onabort 当读取操作被中止时调用
onerror 当读取操作发生错误时调用
onload 当读取操作成功完成时调用
onloadend 当读取操作完成时调用,不管是成功还是失败
onloadstart 当读取操作将要开始之前调用
onprogress 在读取数据过程中周期性调用

使用方法

FileReader通过异步的方式读取文件内容,结果均是通过事件回调获取,下面是一个读取本地txt文件内容的例子:

var input  = document.getElementById("file"); //input file
input.onchange = function(){
    var file = this.files[0];
    if(!!file){
        //读取本地文件,以gbk编码方式输出
        var reader = new FileReader();
        reader.readAsText(file,"gbk");
        reader.onload = function(){
            //读取完毕后输出结果
            console.log(this.result);
        }
    }
}

此外我们还可以通过注册onprogress、onerror等事件,记录文件读取进度或异常行为等等。

读取方式

FileReader提供了四种不同的读取文件的方式,如:readAsArrayBuffer会将文件内容读取为ArrayBuffer对象,readAsBinaryString则将文件读取为二进制串,下面对这四种方式进行简单区分。

首先准备一张图片(6764 字节)和一个txt文本(51字节)作为测试文件:

HTML5 FileReader对象的具体使用方法

接着编写测试代码:

var reader = new FileReader();
// 通过四种方式读取文件
//reader.readAsXXX(file);   
reader.onload = function(){
    //查看文件输出内容
    console.log(this.result);
    //查看文件内容字节大小
    console.log(new Blob([this.result]))
}

readAsDataURL

查看图片输出结果:

HTML5 FileReader对象的具体使用方法

查看txt输出结果:

HTML5 FileReader对象的具体使用方法

很明显,readAsDataURL会将文件内容进行base64编码后输出,这个很好区分。

readAsText

此方法可以通过不同的编码方式读取字符,我们使用utf-8读取

查看图片输出结果:

HTML5 FileReader对象的具体使用方法

查看txt输出结果:

HTML5 FileReader对象的具体使用方法

readAsText读取文件的单位是字符,故对于文本文件,只要按规定的编码方式读取即可;
而对于媒体文件(图片、音频、视频),其内部组成并不是按字符排列,故采用readAsText读取,会产生乱码,同时也不是最理想的读取文件的方式

readAsBinaryString

查看图片输出结果:

HTML5 FileReader对象的具体使用方法

查看txt输出结果:

HTML5 FileReader对象的具体使用方法

与readAsText不同的是,readAsBinaryString函数会按字节读取文件内容。
然而诸如0101的二进制数据只能被机器识别,若想对外可见,还是需要进行一次编码,而readAsBinaryString的结果就是读取二进制并编码后的内容。
尽管readAsBinaryString方法可以按字节读取文件,但由于读取后的内容被编码为字符,大小会受到影响,故不适合直接传输,也不推荐使用。
如:测试的图片文件原大小为6764 字节,而通过readAsBinaryString读取后,内容被扩充到10092个字节

readAsArrayBuffer

查看图片输出结果:

HTML5 FileReader对象的具体使用方法

查看txt输出结果:

HTML5 FileReader对象的具体使用方法

与readAsBinaryString类似,readAsArrayBuffer方法会按字节读取文件内容,并转换为ArrayBuffer对象。
我们可以关注下文件读取后大小,与原文件大小一致。
这也就是readAsArrayBuffer与readAsBinaryString方法的区别,readAsArrayBuffer读取文件后,会在内存中创建一个ArrayBuffer对象(二进制缓冲区),将二进制数据存放在其中。通过此方式,我们可以直接在网络中传输二进制内容。
好了说这么多,那ArrayBuffer到底是个毛?
关于ArrayBuffer对象牵涉的知识点比较多,完全可以单开一篇细说,在此只要简单理解为存放了一段二进制数据的内存空间即可。
而本身ArrayBuffer中的内容对外是不可见的,若要查看其中的内容,就要引入另一个概念:类型化数组
我们可以尝试查看下刚刚通过readAsArrayBuffer方法读取的图片文件内容:

HTML5 FileReader对象的具体使用方法

可以看到,整个图片文件的6764个字节,被分别存储在长度为6764的数组中,而数组中每一个元素的值,为当前字节的十进制数值。
关于ArrayBuffer和类型化数组的概念在此不做深入解释,之后会再写一篇单独讨论。

应用场景

说了这么多,最后还是要落实到FileReader能解决什么问题,下面通过几个例子说明:

在线预览本地文件

我们知道,img的src属性或background的url属性,可以通过被赋值为图片网络地址或base64的方式显示图片。
在文件上传中,我们一般会先将本地文件上传到服务器,上传成功后,由后台返回图片的网络地址再在前端显示。
通过FileReader的readAsDataURL方法,我们可以不经过后台,直接将本地图片显示在页面上。这样做可以减少前后端频繁的交互过程,减少服务器端无用的图片资源,代码如下:

var input  = document.getElementById("file");   // input file
input.onchange = function(){
    var file = this.files[0];
        if(!!file){
            var reader = new FileReader();
            // 图片文件转换为base64
            reader.readAsDataURL(file);
            reader.onload = function(){
                // 显示图片
                document.getElementById("file_img").src = this.result;
        }
    }
}

运行效果如下:

HTML5 FileReader对象的具体使用方法

对于图片上传,我们也可以先将图片转换为base64进行传输,此时由于传输的图片内容就是一段字符串,故上传接口可以当做普通post接口处理,当图片传输到后台后,可以在转换为文件实体存储。
当然,考虑到base64转换效率及其本身的大小,本方法还是适合于上传内容简单或所占内存较小的文件。

二进制数据上传

HTML5体系的建立引入了一大堆新的东西,基于XHR2,我们可以直接上传或下载二进制内容,无需像以往一样通过form标签由后端拉取二进制内容。
简单整理下上传逻辑:
1、通过input[type="file"]标签获取本地文件File对象
2、通过FileReader的readAsArrayBuffer方法将File对象转换为ArrayBuffer
3、创建xhr对象,配置请求信息
4、通过xhr.sendAsBinary直接将文件的ArrayBuffer内容装填至post body后发送
代码实现如下:

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){
                // 响应成功       
            }
        }
    }
}

总结

本篇主要介绍了FileReader对象的属性及应用场景,有了FileReader,我们可以将本地文件读取到内存中。文中我们提到了ArrayBuffer和类型化数组的概念,这使得我们可以在内存中进一步操作二进制数据,关于这部分内容,会在之后的博客中进行归纳。

参考资料

[1] MDN_FileReader
[2] Unicode 和 UTF-8 有何区别

到此这篇关于HTML5 FileReader对象的具体使用方法的文章就介绍到这了,更多相关HTML5 FileReader对象内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章,希望大家以后多多支持三水点靠木!

HTML / CSS 相关文章推荐
纯CSS实现菜单、导航栏的3D翻转动画效果
Apr 23 HTML / CSS
CSS3制作气泡对话框的实例教程
May 10 HTML / CSS
利用CSS3伪元素实现逐渐发光的方格边框
May 07 HTML / CSS
Canvas 文本转粒子效果的实现代码
Feb 14 HTML / CSS
HTML5的结构和语义(3):语义性的块级元素
Oct 17 HTML / CSS
HTML5之SVG 2D入门2—图形绘制(基本形状)介绍及使用
Jan 30 HTML / CSS
video实现有声音自动播放的实现方法
May 20 HTML / CSS
HTML5页面嵌入小程序没有返回按钮及返回页面空白的问题
May 28 HTML / CSS
h5移动端调用支付宝、微信支付的实现
Jun 08 HTML / CSS
html+css实现环绕倒影加载特效
Jul 07 HTML / CSS
能用CSS实现的就不要麻烦JavaScript了
Oct 05 HTML / CSS
css清除浮动clearfix:after的用法详解(附完整代码)
May 21 HTML / CSS
HTML5 Blob对象的具体使用
May 22 #HTML / CSS
详解如何获取localStorage最大存储大小的方法
May 21 #HTML / CSS
html5用video标签流式加载的实现
May 20 #HTML / CSS
video.js支持m3u8格式直播的实现示例
May 20 #HTML / CSS
video实现有声音自动播放的实现方法
May 20 #HTML / CSS
基于html5 canvas做批改作业的小插件
May 20 #HTML / CSS
video下autoplay属性无效的解决方法(添加muted属性)
May 19 #HTML / CSS
You might like
PHP获取163、gmail、126等邮箱联系人地址【已测试2009.10.10】
2009/10/11 PHP
php XMLWriter类的简单示例代码(RSS输出)
2011/09/30 PHP
浅析get与post的一些特殊情况
2014/07/28 PHP
PHP框架性能测试报告
2016/05/08 PHP
php 解析xml 的四种方法详细介绍
2016/10/26 PHP
setInterval 和 setTimeout会产生内存溢出
2008/02/15 Javascript
用jquery生成二级菜单的实例代码
2013/06/24 Javascript
Js nodeType 属性全面解析
2013/11/14 Javascript
深入解析JavaScript中的立即执行函数
2016/05/21 Javascript
Bootstrap 3的box-sizing样式导致UEditor控件的图片无法正常缩放的解决方案
2016/09/15 Javascript
Javascript中内建函数reduce的应用详解
2016/10/20 Javascript
使用JavaScript获取URL中的参数(两种方法)
2016/11/16 Javascript
微信小程序 textarea 组件详解及简单实例
2017/01/10 Javascript
深入理解Node.js中的进程管理
2017/03/13 Javascript
JS实现不用中间变量temp 实现两个变量值得交换方法
2018/02/04 Javascript
JS实现常见的查找、排序、去重算法示例
2018/05/21 Javascript
jQuery插件jsonview展示json数据
2018/05/26 jQuery
jquery实现商品sku多属性选择功能(商品详情页)
2019/12/20 jQuery
原生JS实现汇率转换功能代码实例
2020/05/13 Javascript
Python中的迭代器漫谈
2015/02/03 Python
python实现识别相似图片小结
2016/02/22 Python
Python实现读取TXT文件数据并存进内置数据库SQLite3的方法
2017/08/08 Python
Django logging配置及使用详解
2019/07/23 Python
Python使用贪婪算法解决问题
2019/10/22 Python
解决virtualenv -p python3 venv报错的问题
2021/02/05 Python
IE8下CSS3选择器nth-child() 不兼容问题的解决方法
2016/11/16 HTML / CSS
Bally澳大利亚官网:瑞士奢侈品牌
2018/11/01 全球购物
2014乡镇班子个人对照检查材料思想汇报
2014/09/26 职场文书
预备党员群众路线教育实践活动思想汇报2014
2014/10/25 职场文书
工作疏忽检讨书500字
2014/10/26 职场文书
幸福来敲门观后感
2015/06/04 职场文书
信仰纪录片观后感
2015/06/08 职场文书
2015中秋节晚会主持词
2015/07/01 职场文书
学校体育节班级口号
2015/12/25 职场文书
使用PostGIS完成两点间的河流轨迹及流经长度的计算(推荐)
2022/01/18 PostgreSQL
python playwrigh框架入门安装使用
2022/07/23 Python