FIleReader

FIleReader HTML5

参考链接:https://www.cnblogs.com/hhhyaaon/p/5929492.html
https://www.cnblogs.com/makan/p/4807086.html
使用FileReader对象,web应用程序可以异步的读取存储在用户计算机上的文件(或者原始数据缓冲)内容,可以使用File对象或者Blob对象来指定所要读取的文件或数据.其中File对象可以是来自用户在一个元素上选择文件后返回的FileList对象,也可以来自由拖放操作生成的 DataTransfer对象,还可以是来自在一个HTMLCanvasElement上执行mozGetAsFile()方法后的返回结果。

创建FileReader对象

var reader = new FileReader();

FileReader对象
事件

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

属性

属性名称描述
errorDOMError 在读取文件时发生的错误,只读。
readyState.unsigned short 当前状态值,0—EMPTY 还没有记载任何数据。1–LOADING 正在被记载。2—DONE 已完成全部的读取请求。
resultjsval 读取的文件内容,这个属性只在读取操作完成之后才有效,并且数据的格式取决于读取操作发起的方法。只读

方法

方法名描述
abort():void终止文件读取操作
readAsArrayBuffer(file):void异步按字节读取文件内容,结果用ArrayBuffer对象表示
readAsBinaryString(file):void异步按字节读取文件内容,结果为文件的二进制串,IE浏览器不支持该方法
readAsDataURL(file):void异步读取文件内容,结果用data:url的字符串形式表示
readAsText(file,encoding):void异步按字符读取文件内容,结果用字符串形式表示

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

//1.检测浏览器是否支持FileReader
//测试结果,IE>=10,Google,FF
if (window.FileReader) {
    var fr = new FileReader();
    console.info(fr);
} else {
    alert("Not supported by your browser!");
}
<div class="container">
    <input type="file" id="file" multiple />
    <input type="button" id="btn1" value="选择上传文件" onclick="showFiles();" />
    <h4>
        选择文件如下:
    </h4>
    <blockquote></blockquote>
</div>
var fileBox = document.getElementById('file');
function showFiles() {
    //获取选择文件的数组
    var fileList = fileBox.files;
    for (var i = 0; i < fileList.length; i++) {
        var file = fileList[i];
        readFile(file);
    }
}
//读取文件内容
//reader.readAsArrayBuffer   //将读取结果 封装成 ArrayBuffer ,如果想使用一般需要转换成 Int8Array或DataView
//reader.readAsBinaryString  //在IE浏览器中不支持改方法
//reader.readAsText     该方法有两个参数,其中第二个参数是文本的编码方式,默认值为 UTF-8
//reader.readAsDataURL  //读取结果为DataURL 
//reader.readyState    上传中的状态
function readFile(file) {
    var reader = new FileReader();
    //reader.readAsText(file);
    //中文windows系统 txt 文本多数默认编码 gbk
    reader.readAsText(file, 'gbk');
    console.info(reader.readyState); // 状态值 1
    reader.onload = function (e) {
        console.info(e); //事件对象
        //e.target  FileReader
        //e.total   文件总大小,字节
        //e.type    上传状态‘load’
        //e.timeStamp  还不知道

        console.info(reader.readyState); //状态值 2
        var result = reader.result;
        $('.container blockquote').text(result);
    }
}

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

下面测试一下各种输出方式
首先准备一张图片(6764 字节)和一个txt文本(51字节)作为测试文件

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

readAsText
此方法可以通过不同的编码方式读取字符,我们使用utf-8读取
图片输出结果
文本输出结果:
文本输出结果
readAsText读取文件的单位是字符,故对于文本文件,只要按规定的编码方式读取即可;
而对于媒体文件(图片、音频、视频),其内部组成并不是按字符排列,故采用readAsText读取,会产生乱码,同时也不是最理想的读取文件的方式。

readAsDataURL
图片输出结果
文本输出结果
readAsDataURL会将文件内容进行base64编码后输出

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

readAsArrayBuffer
图片输出结果
文本输出结果
与readAsBinaryString类似,readAsArrayBuffer方法会按字节读取文件内容,并转换为ArrayBuffer对象。
我们可以关注下文件读取后大小,与原文件大小一致。
这也就是readAsArrayBuffer与readAsBinaryString方法的区别,readAsArrayBuffer读取文件后,会在内存中创建一个ArrayBuffer对象(二进制缓冲区),将二进制数据存放在其中。通过此方式,我们可以直接在网络中传输二进制内容。

显示本地图片实例
我们知道,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(e){
                // 显示图片(三种写法)
                document.getElementById("img").src = this.result;
                document.getElementById("img").src = reader.result;
                document.getElementById("img").src = e.target.result;
        }
    }
}

对于图片上传,我们也可以先将图片转换为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){
                // 响应成功       
            }
        }
    }
}
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值