2020 年 4 月 9 日

文件和 FileReader

一个 File 对象继承自 Blob,并扩展了与文件系统相关的功能。

有两种方法可以获取它。

首先,有一个构造函数,类似于 Blob

new File(fileParts, fileName, [options])
  • fileParts – 是一个包含 Blob/BufferSource/String 值的数组。
  • fileName – 文件名字符串。
  • options – 可选对象
    • lastModified – 最后修改的时间戳(整数日期)。

其次,我们更常见的是从 <input type="file"> 或拖放或其他浏览器界面获取文件。在这种情况下,文件会从操作系统获取这些信息。

由于 File 继承自 BlobFile 对象具有相同的属性,以及

  • name – 文件名,
  • lastModified – 最后修改时间戳。

这就是我们如何从 <input type="file"> 获取 File 对象。

<input type="file" onchange="showFile(this)">

<script>
function showFile(input) {
  let file = input.files[0];

  alert(`File name: ${file.name}`); // e.g my.png
  alert(`Last modified: ${file.lastModified}`); // e.g 1552830408824
}
</script>
请注意

输入可能选择多个文件,因此 input.files 是一个包含它们的类似数组的对象。这里我们只有一个文件,所以我们只取 input.files[0]

FileReader

FileReader 是一个对象,其唯一目的是从 Blob(以及 File)对象读取数据。

它使用事件传递数据,因为从磁盘读取可能需要时间。

构造函数

let reader = new FileReader(); // no arguments

主要方法

  • readAsArrayBuffer(blob) – 以二进制格式 ArrayBuffer 读取数据。
  • readAsText(blob, [encoding]) – 以给定编码(默认情况下为 utf-8)读取数据作为文本字符串。
  • readAsDataURL(blob) – 读取二进制数据并将其编码为 base64 数据 URL。
  • abort() – 取消操作。

选择 read* 方法取决于我们喜欢的格式以及我们如何使用数据。

  • readAsArrayBuffer – 用于二进制文件,执行低级二进制操作。对于高级操作,例如切片,File 继承自 Blob,因此我们可以直接调用它们,而无需读取。
  • readAsText – 用于文本文件,当我们想要获取字符串时。
  • readAsDataURL – 当我们想要在 img 或其他标签的 src 中使用此数据时。有一个替代方法来读取文件,如 Blob 章中所述:URL.createObjectURL(file)

随着读取的进行,会有一些事件

  • loadstart – 开始加载。
  • progress – 在读取过程中发生。
  • load – 没有错误,读取完成。
  • abort – 调用 abort()
  • error – 发生错误。
  • loadend – 读取完成,无论成功还是失败。

读取完成后,我们可以访问结果为

  • reader.result 是结果(如果成功)
  • reader.error 是错误(如果失败)。

最常用的事件当然是 loaderror

以下是一个读取文件的示例

<input type="file" onchange="readFile(this)">

<script>
function readFile(input) {
  let file = input.files[0];

  let reader = new FileReader();

  reader.readAsText(file);

  reader.onload = function() {
    console.log(reader.result);
  };

  reader.onerror = function() {
    console.log(reader.error);
  };

}
</script>
FileReader 用于 blob

Blob 章中所述,FileReader 不仅可以读取文件,还可以读取任何 blob。

我们可以使用它将 blob 转换为另一种格式

  • readAsArrayBuffer(blob) – 转换为 ArrayBuffer
  • readAsText(blob, [encoding]) – 转换为字符串(TextDecoder 的替代方法),
  • readAsDataURL(blob) – 转换为 base64 数据 URL。
FileReaderSync 可在 Web Workers 中使用

对于 Web Workers,还存在 FileReader 的同步变体,称为 FileReaderSync

它的读取方法read*不会生成事件,而是像普通函数一样返回结果。

不过,这只是在 Web Worker 内部,因为在 Web Worker 中,从文件读取时可能发生的同步调用延迟并不重要。它们不会影响页面。

总结

File 对象继承自 Blob

除了 Blob 方法和属性外,File 对象还具有 namelastModified 属性,以及从文件系统读取的内部能力。我们通常从用户输入中获取 File 对象,例如 <input> 或拖放事件 (ondragend)。

FileReader 对象可以从文件或 Blob 中读取,以三种格式之一

  • 字符串 (readAsText)。
  • ArrayBuffer (readAsArrayBuffer)。
  • 数据 URL,base-64 编码 (readAsDataURL)。

不过,在许多情况下,我们不必读取文件内容。就像我们对 Blob 所做的那样,我们可以使用 URL.createObjectURL(file) 创建一个简短的 URL,并将其分配给 <a><img>。这样,文件就可以作为画布的一部分下载或显示为图像等。

如果我们要通过网络发送 File,也很容易:网络 API(如 XMLHttpRequestfetch)可以原生接受 File 对象。

教程地图

评论

在评论之前阅读此内容…
  • 如果您有任何改进建议,请提交 GitHub 问题或拉取请求,而不是评论。
  • 如果您无法理解文章中的某些内容,请详细说明。
  • 要插入少量代码,请使用<code>标签,对于多行代码,请使用<pre>标签,对于超过10行的代码,请使用沙箱(plnkrjsbincodepen…)