上篇文章,简述了使用 javascript 对于文件上传的一些操作,例如,当用户想要上传,或者拖拽上传文件的时候。如何获得文件对象。那么,这篇文章,将简单的讲述一些读取文件数据的操作。

FileReader

FileReader 只有一个功能,那就是读取文件数据并且将其存储在 javascript 变量中,此 API 专门被设计成模拟(类似) XMLHttpRequest 操作,因为它们两个都是从外部资源加载数据(不包括浏览器)。并且此 API 被设计成异步的(asynchronously),所以不会引起浏览器的锁死。

FileReader 可以将数据读取成各种格式,而且在读取数据的时候,必须要求使用这几种格式,这几种格式如下,必须通过调用这几种格式才能读取数据。

readAsText() – 返回文本数据(text/plain)。
readAsBinaryString() – 返回此文件被编码的二进制数据 (已弃用– 使用 readAsArrayBuffer() 代替)。
readAsArrayBuffer() – 返回此文件的一个ArrayBuffer(二进制数据缓冲)(适合二进制数据,例如图像文件)数据。
readAsDataURL() – 返回此文件的 <a href="http://en.wikipedia.org/wiki/Data_URI_scheme" title="Data URI scheme" target="_blank">data URL</a>

没中方法都初始化一个文件读取动作,类似于 XHR 对象的 send() 方法初始化一个 http 请求。所以,必须对此绑定一些事件来监听文件读取的发生,例如 load 事件,表示文件读取完成,代码如下:

var reader = new FileReader();
reader.onload = function(event) {
    var contents = event.target.result;
    console.log("File contents: " + contents);
};//文件读取完成

reader.onerror = function(event) {
    console.error("File could not be read! Code " + event.target.error.code);
};//文件读取错误

reader.readAsText(file);//以文本方式读取

此代码主要是通过文本(text/plain)凡是来读取数据,并将其在 控制台(console) 显示,当文件被成功读取,onload 事件触发,当文件读取出错, onerror 事件触发,在事件内部,FileReader 的实例,应该使用 event.target 而不是直接使用保存 reader 的变量,读取文件成功时, result 属性保存文件内容,读取文件失败时, result 属性保存错误信息。

使用 data URIs 读取数据

稍微改变一下上面的代码,就可以实现使用 data URIs/data URLs 读取数据,尤其是从本地读取比较小的图片,读取并且在浏览器中显示,是非常便利的。

var reader = new FileReader();
reader.onload = function(event) {//成功读取
    var dataUri = event.target.result,//数据内容
        img     = document.createElement("img");//创建一个 img 对象

    img.src = dataUri; //设置 img 对象的 src 属性值为 dataUri
    document.body.appendChild(img);//将 img 插入到 body 中
};

reader.onerror = function(event) {
    console.error("File could not be read! Code " + event.target.error.code);
};//读取文件错误是发生

reader.readAsDataURL(file);// 以 data url 方式读取数据

此代码将图片从本地以 data url 方式读取后,存入 img 对象的 src 属性中,然后直接在页面显示,如果可以,你可以直接将此图片放到页面上进行处理,不过要使用 <canvas> 才行。

var reader = new FileReader();
reader.onload = function(event) {
    var dataUri = event.target.result,
        context = document.getElementById("mycanvas").getContext("2d"),
    img     = new Image();
    img.onload = function() {// 等待图像文件被加载完
        canvas.drawImage(img, 100, 100);
    };
    img.src = dataUri;
};

reader.onerror = function(event) {
    console.error("File could not be read! Code " + event.target.error.code);
};

此代码将图像文件加载完成之后,放到一个 canvas 画布中进行处理。

以 ArrayBuffers 方式读取

ArrayBuffer 最初是作为 WebGL 的一部分的,ArrayBuffer 代表一个可以存储任意任意大小的数字的一个有限的区域,此种方式读取的数据,必须使用特殊的方式访问,例如 Int8Array ,将此底层的数据视为 8 位的符号整数。或者 Float32Array 将其视为 32 位的浮点数,这些都被叫做类型化数组/格式化数组,都被强制的使用某种数据格式来使用,而不像普通格式的数据那样。

ArrayBuffer 主要用来处理二进制数据文件,已能够对数据具有更细粒度的控制,并且远远超出此篇文章解释的范围。反正在使用的时候,只要记住,你可以很简单的将一个文件读取为二进制缓冲,并且可以简单地将此数据通过 XHR 的 send() 方法发送给后端服务器(当然了,你必须从服务器上接受此二进制缓冲,并且重建此文件),但是浏览器还必须完整的支持 XMLHttpRequest Level 2,不过可惜的是,只有 IE10 以上的现代浏览器才支持。

预告
FileReader 的使用很简单,但是,如果你知道如何使用 XMLHttpRequest 的话,没有理由你不会用这种方式读取文件,下节,将介绍更多的关于 FileReader 的事件,和更多可能的错误。