译注:原文是《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. Celery最佳实践(转)

    原文:http://my.oschina.net/siddontang/blog/284107 英文原文:https://denibertovic.com/posts/celery-best-prac ...

  2. 百度天气接口api

    百度天气接口 以GET形式提交,返回JSON或XML URL:http://api.map.baidu.com/telematics/v3/weather?location={城市名}&out ...

  3. Spark源码分析之Checkpoint的过程

    概述 checkpoint 的机制保证了需要访问重复数据的应用 Spark 的DAG执行图可能很庞大,task 中计算链可能会很长,这时如果 task 中途运行出错,那么 task 的整个需要重算非常 ...

  4. nmon 命令

    nmon 命令 用途 以交互方式显示本地系统统计信息并以记录方式记录系统统计信息. 语法 交互方式: nmon [ -h ] nmon [ -s < seconds >] [ -c < ...

  5. Spring中基于Java的配置@Configuration和@Bean用法

    spring中为了减少xml中配置,可以声明一个配置类(例如SpringConfig)来对bean进行配置. 一.首先,需要xml中进行少量的配置来启动Java配置: <?xml version ...

  6. 从getApplicationContext和getApplication再次梳理Android的Application正确用法

    原文地址http://blog.csdn.net/ly502541243/article/details/52105466 原文地址http://blog.csdn.net/ly502541243/a ...

  7. pyqt简单介绍和使用

    QML和PyQT5联合编程 安装pyqt pip3 install PyQT5 main.QML import QtQuick 2.2 import QtQuick.Controls 1.1 impo ...

  8. Git 系列——第一步安装 Git

    之前也没有用过什么版本控制的工具,唯一用过的就是 SVN 了,不过也只是简单的使用而已,比如写好代码就签入,没了?是的,没了. 于是接触到了 Git 这个分布式版本控制软件,接下来就让我们好好学习,天 ...

  9. linux改变apt-get安装源

    最近自己装了个ubuntu kylin 在使用的过程中发现,系统的apt-get 的源有毛病,总是安装不了软件. 感觉应该是传说中的墙的原因,所以准备换到阿里云的源. 下面是步骤: 1.复制原文件备份 ...

  10. MapReduce 过程详解 (用WordCount作为例子)

    本文转自 http://www.cnblogs.com/npumenglei/ .... 先创建两个文本文件, 作为我们例子的输入: File 1 内容: My name is Tony My com ...