FileReader类型实现的是一种异步文件读取机制。可以把FileReader想象成XMLHttpRequest,区别只是它读取的是文件系统,而不是远程服务器。为了读取文件中的数据,FileReader提供了如下几个方法。
这些读取文件的方法为灵活地处理文件数据提供了极大便利。例如,可以读取图像文件并将其保存为数据URI,以便将其显示给用户,或者为了解析方便,可以将文件读取为文本形式。由于读取过程是异步的,因此FileReader也提供了几个事件。其中最有用的三个事件是progress、error和load,分别表示是否又读取了新数据、是否发生了错误以及是否已经读完了整个文件。每过50ms左右,就会触发一次progress事件,通过事件对象可以获得与XHR的progress事件相同的信息(属性):lengthComputable、loaded和total。另外,尽管可能没有包含全部数据,但每次progress事件中都可以通过FileReader的result属性读取到文件内容。由于种种原因无法读取文件,就会触发error事件。触发error事件时,相关的信息将保存到FileReader的error属性中。这个属性中将保存一个对象,该对象只有一个属性code,即错误码。这个错误码是1表示未找到文件,是2表示安全性错误,是3表示读取中断,是4表示文件不可读,是5表示编码错误。文件成功加载后会触发load事件,如果发生了error事件,就不会发生load事件,以下是一个使用上述三个事件的例子。
<form method="post" action="" class="mb20"><input type="file" name="files-list" id="files-list" multiple></form> <p><span id="progress"></span><br><span id="output"></span></p> <script type="text/javascript"> var filesList = document.getElementById("files-list"); filesList.addEventListener("change",function(event){ var info="",output=document.getElementById("output"),progress=document.getElementById("progress"); event=event.target || event.srcElement; var files=event.files,type="default",reader=new FileReader(); if(/image/.test(files[0].type)){ reader.readAsDataURL(files[0]); type="image"; }else{ reader.readAsText(files[0]); type="text"; } reader.onerror=function(){ output.innerHTML="Could not read file(error code is "+reader.error.code+")"; }; reader.onprogress=function(event){ if(event.lengthComputable){ progress.innerHTML=event.loaded+"/"+event.total; } }; reader.onload=function(){ var html=""; switch(type){ case "image":html='<img src="'+reader.result+'">';break; case "text":html=reader.result;break; } output.innerHTML=html; }; },false); </script>
这个例子读取了表单字段中选择的文件,并将其内容显示在了页面中。如果文件有MIMI类型,表示文件是图像,因此在load事件中就把它保存为数据URI,并在页面中将这幅图像显示出来。如果文件不是图像,则以字符串形式读取文件内容,然后如实在页面中显示读取到的内容。这里使用了progress事件来跟踪读取了多少字节的数据,而error事件则用于监控发生的错误。如果想中断读取过程,可以调用abort()方法,这样就会触发abort事件。在触发load、error或abort事件后,会触发另一个事件loadend。loadend事件发生就意味着已经读取完整个文件,或者读取时发生了错误,或者读取过程被中断。实现File API的所有浏览器都支持readASText()和readAsDataURL()方法。但IE 10 PR 2并未实现readAsBinaryString()和readAsArrayBuffer()方法。