译注:原文是《JavaScript高级程序设计》的作者Nicholas Zakas写的,本翻译纯属为自己学习而做,仅供参考。原文链接:这里


FileReader对象用来读取浏览器可以访问的文件的内容。在我前一篇blog中,你学习到了如何使用FileReader对象轻松读取文件,并将文件内容转换为各种形式。FileReader在很多方面和XMLHttpRequest非常相似。

进度事件

progress事件变得如此普遍,以致实际上它们写在一个独立的规范[1]里面。这些事件设计用来表示数据传输的进度。这些传输不只发生在从服务器端请求数据的时候,而且也发生在从磁盘上请求数据的时候,这都是FileReader可以做的。

这里有6个进度事件:

  • loadstart – 表示加载数据的进度开始,这个事件总是首先被触发。
  • progress – 在加载数据过程中多次被触发,可以访问中间的数据。
  • error – 当加载失败时触发。
  • abort – 当通过调用abort()取消数据加载时触发(在XMLHttpRequest和FileReader上都可使用)。
  • load – 只有当所有数据被成功读取后才触发。
  • loadend – 当对象停止传输数据时触发。在error,abort和load后始终被触发。

error和load事件我们在前一篇blog已经讨论了。其他事件让你更好地控制在数据传输。

跟踪进度

当你想要跟踪一个文件读取的进度,你可以使用progress事件。这个事件对象包含了3个属性来监控数据的传输:

  • lengthComputable – 一个布尔值,表示浏览器是否能侦测数据的完整大小。
  • loaded – 已经读取的数据字节数大小。
  • total – 所要读取的数据字节数总大小

这些数据是为了生成一个使用了progress事件数据的进度条。例如,你可以使用HTML5<progress>元素来监控文件的读取进度。你可以像下面的代码一样让你的进度条和实际数据相关联:

demo.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var reader = new FileReader(),
  progressNode = document.getElementById("my-progress");
reader.onprogress = function(event) {   
  if (event.lengthComputable) {
    progressNode.max = event.total;
    progressNode.value = event.loaded;
  }
};
reader.onloadend = function(event) {
  var contents = event.target.result,
     error = event.target.error;
  
  if (error != null) {
    console.error("File could not be read! Code " + error.code);
  } else {
    progressNode.max = 1;
    progressNode.value = 1;
    console.log("Contents: " + contents);
  }
};
reader.readAsText(file);

这与Gmail用拖拽方式进行文件上传的方法相似,拖拽一个文件到email后你可以立即看到一个进度条。这个进度条表示有多少文件已经被传输到服务器。

错误处理

即使你已经在读取一个本地文件,但仍然有可能读取失败。在File API规范[2]中定义了4种错误类型:

  • NotFoundError – 找不到该文件。  
  • SecurityError – 文件或者读取操作可能包含某些危险。浏览器有一些补救措施来处理这种情况,但一般来讲,如果加载到浏览器的文件有危险或者浏览器被限制了不能有太多的读取动作,你将会看到这个错误。  
  • NotReadableError – 文件存在但不可读,大部分情况可能是权限问题。  
  • EncodingError – 主要当尝试将文件内容读取为一个数据URI并且数据URI结果的长度超过浏览器可支持的最大长度时,会抛出这个错误。

当读取文件发生错误时,上述的4个错误类型之一会被实例化,并分配到FileReader对象的error属性上。至少,规范上是这样写的。实际上,浏览器是通过一个FileError对象来实现的,FileError对象有一个code属性,表示当前发生的错误类型。每个错误类型通过一个数字常量来表示:

  • FileError.NOT_FOUND_ERR对应找不到该文件错误。
  • FileError.SECURITY_ERR对应安全错误。
  • FileError.NOT_READABLE_ERR对应不可读错误。
  • FileError.ENCODING_ERR对应编码错误。
  • FileError.ABORT_ERR当没有读取进度时调用abort()方法。

你可以在error或者loadend事件中测试错误类型:

demo.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
var reader = new FileReader();
reader.onloadend = function(event) {
  var contents = event.target.result,
    error = event.target.error;
  if (error != null) {
    switch (error.code) {
      case error.ENCODING_ERR:
        console.error("Encoding error!");
        break;
      case error.NOT_FOUND_ERR:
        console.error("File not found!");
        break;
      case error.NOT_READABLE_ERR:
        console.error("File could not be read!");
        break;
      case error.SECURITY_ERR:
        console.error("Security issue with file!");
        break;
      default:
        console.error("I have no idea what's wrong!");
    }
  } else {
    progressNode.max = 1;
    progressNode.value = 1;
    console.log("Contents: " + contents);
  }
};
reader.readAsText(file);

下集预告

FileReader是一个全面的对象,有着非常多的功能,并且和XMLHttpRequest很相似。在学习了这3篇blog之后,你现在应该可以使用JavaScript来读取文件数据,如果需要的话,还可以将数据发送回给服务器。尽管如此,File API的功能和内容比我们在这个系列里讨论的东西要多得多,在下一章你将学习到一个强大全新的功能设计来处理文件。

相关链接

  1. Progress Events
  2. File API

在JavaScript中进行文件处理,第三部分:处理事件和错误的更多相关文章

  1. 在JavaScript中进行文件处理,第五部分:Blobs

    译注:原文是<JavaScript高级程序设计>的作者Nicholas Zakas写的,本翻译纯属为自己学习而做,仅供参考.原文链接:这里 到目前为止,这个系列的帖子集中在和这些文件交互- ...

  2. 在JavaScript中进行文件处理,第一部分:基础

    译注:原文是<JavaScript高级程序设计>的作者Nicholas Zakas写的,本翻译纯属为自己学习而做,仅供参考.原文链接:这里 很多年前,我在一次Goole面试被问到,如何在w ...

  3. 在JavaScript中进行文件处理,第二部分:文件读取

    译注:原文是<JavaScript高级程序设计>的作者Nicholas Zakas写的,本翻译纯属为自己学习而做,仅供参考.原文链接:这里 在我的前一篇blog中,我介绍了在JavaScr ...

  4. Javascript中的对象和原型(三)(转载)

    在Javascript中的对象和原型(二)中我们提到,用构造函数创建的对象里面,每个对象之间都是独立的,这样就会降低系统资源的利用率,解决这样问题,我们就要用到下面提到的原型对象. 一 原型对象 原型 ...

  5. Javascript中对文字编码的三个函数

    JavaScript中对文字编码主要有3个函数 escape,encodeURI, encodeURIComponent 相应3个解码函数 unescape, decodeURI, decodeURI ...

  6. 在JavaScript中进行文件处理,第四部分:对象URLs

    译注:原文是<JavaScript高级程序设计>的作者Nicholas Zakas写的,本翻译纯属为自己学习而做,仅供参考.原文链接:这里 学习到这里,你已经了解在传统方式中如何使用文件, ...

  7. JavaScript中有对字符串编码的三个函数:escape,encodeURI,encodeURIComponent

    JavaScript中有三个可以对字符串编码的函数,分别是: escape,encodeURI,encodeURIComponent,相应3个解码函数:unescape,decodeURI,decod ...

  8. Delphi中实现文件拷贝的三种方法

    1.调用API函数procedure CopyFile(FromFileName,ToFileName:string);varf1,f2:file;BeginAssignFile(f1,FromFil ...

  9. javascript中继承方式及优缺点(三)

    文以<JavaScript高级程序设计>上的内容为骨架,补充了ES6 Class的相关内容,从我认为更容易理解的角度将继承这件事叙述出来,希望大家能有所收获. 1. 继承分类 先来个整体印 ...

随机推荐

  1. linux IO多路复用POLL机制深入分析

    POLL机制的作用这里就不进行介绍,根据linux man手册,解释为在一个文件描述符上等待某个事件.按照抽象一点的理解,当某个事件被触发(条件被满足),文件描述符变为有状态,那么用户空间可以根据此进 ...

  2. java-mybaits-00701-与spring整合

    1.1     整合思路   需要spring通过单例方式管理SqlSessionFactory. spring和mybatis整合生成代理对象,使用SqlSessionFactory创建SqlSes ...

  3. Hook?

    public interface IHook { /// <summary> /// 二维地图控件对象 /// </summary> ESRI.ArcGIS.Controls. ...

  4. Openstack(四)Mysql主从

    4.1 安装mysql 4.1.1 安装依赖 # yum install vim gcc gcc-c++ wget autoconf  net-tools lrzsz iotop lsof iotop ...

  5. c#将十进制转64进制

    //由于用于文件命名,所以将64位中的+转换为=,/转换为_     static char[] digits = {          '0' , '1' , '2' , '3' , '4' , ' ...

  6. mysql索引之聚簇索引与非聚簇索引

    1 数据结构及算法基础 1.1 索引的本质 官方定义:索引(Index)是帮助MySQL高效获取数据的数据结构 本质:索引是数据结构 查询是数据库的最主要功能之一.我们都希望查询速度能尽可能快,因此数 ...

  7. 53. Maximum Subarray(动态规划 求最大子数组)

      Find the contiguous subarray within an array (containing at least one number) which has the larges ...

  8. [转]Birdfont 2.10 发布,字体编辑器

    最近在忙大数据.黑天鹅算法实盘测试 许久没有更新字库方面的资料,汗一个... 今天转一个 :Birdfont 2.10 发布,字体编辑器 字体编辑器,向来很少,除了fontlab的几个昂贵的商业版,就 ...

  9. Ruby 安装和gem配置

    在linux或mac等*unix系统下可以使用rvm来进行ruby的配置和管理. 安装方法 (需要curl) curl -L get.rvm.io | bash -s stable rvm官方网站: ...

  10. Python3 pandas用法大全

    Python3 pandas用法大全 一.生成数据表 1.首先导入pandas库,一般都会用到numpy库,所以我们先导入备用: import numpy as np import pandas as ...