11日 六月 2019
本资料仅提供以下语言版本:English, 日本語, Русский。请 帮助我们 将其翻译为 简体中文 版本。

File and FileReader

A File object inherits from Blob and is extended with filesystem-related capabilities.

There are two ways to obtain it.

First, there’s a constructor, similar to Blob:

new File(fileParts, fileName, [options])
  • fileParts – is an array of Blob/BufferSource/String value, same as Blob.
  • fileName – file name string.
  • options – optional object:
    • lastModified – a timestamp (integer date) of last modification.

Second, more often we get a file from <input type="file"> or drag’n’drop or other browser interfaces. Then the file gets these from OS.

For instance:

<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>
请注意:

The input may select multiple files, so input.files is an array-like object with them. Here we have only one file, so we just take input.files[0].

FileReader

FileReader is an object with the sole purpose of reading data from Blob (and hence File too) objects.

It delivers the data using events, as reading from disk may take time.

The constructor:

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

The main methods:

  • readAsArrayBuffer(blob) – read the data as ArrayBuffer
  • readAsText(blob, [encoding]) – read the data as a string (encoding is utf-8 by default)
  • readAsDataURL(blob) – encode the data as base64 data url.
  • abort() – cancel the operation.

As the reading proceeds, there are events:

  • loadstart – loading started.
  • progress – occurs during reading.
  • load – no errors, reading complete.
  • abortabort() called.
  • error – error has occurred.
  • loadend – reading finished with either success or failure.

When the reading is finished, we can access the result as:

  • reader.result is the result (if successful)
  • reader.error is the error (if failed).

The most widely used events are for sure load and error.

Here’s an example of reading a file:

<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 for blobs

As mentioned in the chapter Blob, FileReader works for any blobs, not just files.

So we can use it to convert a blob to another format:

  • readAsArrayBuffer(blob) – to ArrayBuffer,
  • readAsText(blob, [encoding]) – to string (an alternative to TextDecoder),
  • readAsDataURL(blob) – to base64 data url.
FileReaderSync is available for workers only

For Web Workers, there also exists a synchronous variant of FileReader, called FileReaderSync.

Its reading methods read* do not generate events, but rather return a result, as regular functions do.

That’s only inside a Web Worker though, because delays in synchronous calls, that are possible while reading from files, in Web Workers are less important. They do not affect the page.

Summary

File objects inherit from Blob.

In addition to Blob methods and properties, File objects also have fileName and lastModified properties, plus the internal ability to read from filesystem. We usually get File objects from user input, like <input> or drag’n’drop.

FileReader objects can read from a file or a blob, in one of three formats:

  • String (readAsText).
  • ArrayBuffer (readAsArrayBuffer).
  • Data url, base-64 encoded (readAsDataURL).

In many cases though, we don’t have to read the file contents. Just as we did with blobs, we can create a short url with URL.createObjectURL(file) and assign it to <a> or <img>. This way the file can be downloaded or shown up as an image, as a part of canvas etc.

And if we’re going to send a File over a network, that’s also easy, as network API like XMLHttpRequest or fetch natively accepts File objects.

教程路线图

评论

在评论之前先阅读本内容…
  • 欢迎你在文章下添加补充内容、提出你的问题或回答提出的问题。
  • 使用 <code> 标签插入几行代码,对于多行代码 — 可以使用 <pre>,对于超过十行的代码 — 建议使用沙箱(plnkrJSBincodepen 等)。
  • 如果你无法理解文章中的内容 — 请详细说明。