使用FileReader进行文档读取

最近在做的一个项目,需要读取用户上传的文档并进行本地存储,学习了一下FileReader。

本文简单介绍了FileReader以及两个FileReader的使用场景:文档读取和图片预览。

DEMO: https://dumengjie.github.io/blog-demos/FileReader/

扩展阅读: 使用localStorage进行本地存储

FileReader是什么

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

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

构造函数

FileReader() 返回一个新构造的 FileReader

想要创建一个 FileReader 对象,很简单,如下:

let reader = new FileReader();

方法

FileReader接口有4个方法,其中3个用来读取文档,另一个用来中断读取。无论读取成功或失败,方法并不会返回读取结果,这一结果存储在result属性中。

方法名 参数 描述
readAsBinaryString file 将文档读取为二进制编码
readAsText file,[encoding] 将文档读取为文本
readAsDataURL file 将文档读取为DataURL
abort (none) 终端读取操作

事件处理进程

事件 调用时机
onabort 当读取操作被中止时调用
onerror 当读取操作发生错误时调用
onload 当读取操作成功完成时调用
onloadend 当读取操作完成时调用,不管是成功还是失败.该处理进程在 onload 或者 onerror 之后调用
onloadstart 当读取操作将要开始之前调用
onprogress 在读取数据过程中周期性调用

了解了这些基本上就可以进行开发了,如果想了解更多,请阅读 FileReader

读取文本

对于 type="file"input 元素,用户选择文档上传后会生成一个 FileList 对象,结构如下:

// FileList对象
{
 0: {
 lastModified: 1482289489971,
 lastModifiedDate: Wed Dec 21 2016 11:04:49 GMT+0800,
 name: "index.html",
 size: 1325,
 type: "text/html",
 },
 1: {
 ...
 },
 length: 2
}

我们从中可以获取文档名、修改时间、大小和文档类型等信息,文档内容也是包含在里面的,不过需要 FileReader 的读取文档方法才能获取,对于纯文本,我们使用 readAsText 方法,如下:

//FileReader读取文档内容
var reader = new FileReader();
reader.readAsText(files[0], 'UTF-8');
reader.onload = function (e){
 // urlData就是对应的文档内容
 var urlData = this.result;
};

为了大家更直观的理解,我写了个demo,配合 localStorage 实现本地文档读取与本地存储,对于 localStorage 的使用,请查看 使用localStorage进行本地存储

图片预览

FileReader 的另一个文档读取方法 readAsDataURL ,可以将图片文档转换为 base64 编码。这个方法非常有用,可以实现本地图片预览,直接上个MDN的 demo ,源码:

<!doctype html>
<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
<title>Image preview example</title>
<script type="text/javascript"> 
oFReader = new FileReader(), rFilter = /^(?:image\/bmp|image\/cis\-cod|image\/gif|image\/ief|image\/jpeg|image\/jpeg|image\/jpeg|image\/pipeg|image\/png|image\/svg\+xml|image\/tiff|image\/x\-cmu\-raster|image\/x\-cmx|image\/x\-icon|image\/x\-portable\-anymap|image\/x\-portable\-bitmap|image\/x\-portable\-graymap|image\/x\-portable\-pixmap|image\/x\-rgb|image\/x\-xbitmap|image\/x\-xpixmap|image\/x\-xwindowdump)$/i;

oFReader.onload = function (oFREvent){
 document.getElementById("uploadPreview").src = oFREvent.target.result;
};

function loadImageFile(){
 if (document.getElementById("uploadImage").files.length === 0) { return; }
 var oFile = document.getElementById("uploadImage").files[0];
 if (!rFilter.test(oFile.type)) { alert("You must select a valid image file!"); return; }
 oFReader.readAsDataURL(oFile);
}
</script>
</head>

<body onload="loadImageFile();">
 <form name="uploadForm">
 <table>
 <tbody>
 <tr>
 <td><img id="uploadPreview" style="width: 100px; height: 100px;" src="" alt="Image preview" /></td>
 <td><input id="uploadImage" type="file" name="myPhoto" onchange="loadImageFile();" /></td>
 </tr>
 </tbody>
 </table>

 <p><input type="submit" value="Send" /></p>
 </form>
</body>
</html>