FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据。

其中File对象可以是来自用户在一个<input>元素上选择文件后返回的FileList对象,也可以来自拖放操作生成的 dataTransfer对象,还可以是来自在一个Canvas上执行mozGetAsFile()方法后返回结果。

 

FileReader对象有以下几个方法:

1.abort()

用来终止该读取操作,无返回值。

 

2.readAsArrayBuffer()

开始读取指定的Blob对象或File对象中的内容。当读取操作完成时,会触发onload()事件,因此可以自定义onload()事件,同时,result属性中将包含一个ArrayBuffer对象以表示所读取文件的内容。

关于ArrayBuffer对象,表示一个通用的,固定长度的二进制数据缓冲区。你不能直接操纵ArrayBuffer的内容相反,你应该创建一个表示特定格式的buffer的类型化数组对象(typed array objects)或数据视图对象DataView 来对buffer的内容进行读取和写入操作。

 

如何从现有数据获取数组缓冲区?

  1. 从一个本地文件(一般是从<input>和拖拽生成的dataTransfer对象上获取本地文件)
  2. 从一个Base64字符串
function _base64ToArrayBuffer(base64) {
    var binary_string =  window.atob(base64);
    var len = binary_string.length;
    var bytes = new Uint8Array( len );
    for (var i = 0; i < len; i++)        {
        bytes[i] = binary_string.charCodeAt(i);
    }
    return bytes.buffer;
}

参考:https://stackoverflow.com/questions/21797299/convert-base64-string-to-arraybuffer

 

3.readAsBinaryString()

将File对象或者Blob对象读取为原始二进制数据

 

4.readAsDataURL()

将File对象或者Blob对象读取为下图所示的形式。

上图是我上传的一个文本文件的结果,头部指明了文件的类型以及编码方式,在编码方式之后就是该文件的base64编码了。

这个方法在上传预览图片时非常有用。例子如下:TXWSLYF.github.io/demos/HTML5图片上传预览/HTML5图片上传预览.html

 

5.readAsText()

开始读取指定的Blob对象或File对象中的内容,result属性中将包含一个字符串以表示所读取的文件内容。

 

以上说了FIleReader()的4中读取方式,那么它们又有什么联系和区别呢?

 

1.base64编码和原始二进制数据之间的互相转化

base64编码是通过readAsDataURL()方法得到的,原始二进制数据是通过readAsBinaryString()方法的到的。他们之间的相互转化可以通过使用以下两个方法:

window.atob()和window.btoa()

atob() 函数能够解码通过base-64编码的字符串数据。相反地,btoa() 函数能够从二进制数据“字符串”创建一个base-64编码的ASCII字符串。

atob() 和 btoa() 均使用字符串。

看下面的例子:

for (i; i < fileList.length; i++) {
        var fileReader = new FileReader();
        fileReader.onload = function (e) {
            var result = e.target.result;
            console.log(result)
            // console.log(window.btoa(result))
        };
        console.log(fileList[i].type);
        fileReader.readAsDataURL(fileList[i]);
        // fileReader.readAsBinaryString(fileList[i])
    }

  

得到了上传文件的base64编码以及文件类型

再看下面一段代码:

  for (i; i < fileList.length; i++) {
        var fileReader = new FileReader();
        fileReader.onload = function (e) {
            var result = e.target.result;
            // console.log(result)
            console.log(window.btoa(result))
        };
        console.log(fileList[i].type);
        // fileReader.readAsDataURL(fileList[i]);
        fileReader.readAsBinaryString(fileList[i])
    }
});

  

可以看到二进制数据被编码为base64的数据。

 

2.base64编码字符串转换为Blob对象

changeDataUrlToBlob = (dataUrl) => {
        let type = dataUrl.split(';')[0];
        let data = window.atob(dataUrl.split(',')[1]);
        let ia = new Uint8Array(data.length);
        for (let i = 0; i < data.length; i++) {
            ia[i] = data.charCodeAt(i);
        }
        let blob = new Blob([ia], { type: type });
        return blob;
    };

其中dataUrl参数是由readAsDataURL()方法返回的包含文件类型以及bae64编码的字符串。

 

3.Blob对象转换为base64编码字符串

window.URL.createObjectURL(blob)