2019-03-17 20:05:02 +03:00
# File and FileReader
2019-05-29 21:38:58 +03:00
A [File ](https://www.w3.org/TR/FileAPI/#dfn-file ) object inherits from `Blob` and is extended with filesystem-related capabilities.
2019-03-17 20:05:02 +03:00
There are two ways to obtain it.
First, there's a constructor, similar to `Blob` :
``` js
new File ( fileParts , fileName , [ options ] )
```
2019-07-04 18:13:00 +03:00
- **`fileParts` ** -- is an array of Blob/BufferSource/String values.
2019-03-17 20:05:02 +03:00
- **`fileName` ** -- file name string.
- **`options` ** -- optional object:
2019-07-03 17:19:00 +03:00
- **`lastModified` ** -- the timestamp (integer date) of last modification.
2019-03-17 20:05:02 +03:00
2019-07-04 18:13:00 +03:00
Second, more often we get a file from `<input type="file">` or drag'n'drop or other browser interfaces. In that case, the file gets this information from OS.
2019-03-17 20:05:02 +03:00
2019-07-04 18:13:00 +03:00
As `File` inherits from `Blob` , `File` objects have the same properties, plus:
2019-07-03 17:19:00 +03:00
- `name` -- the file name,
- `lastModified` -- the timestamp of last modification.
That's how we can get a `File` object from `<input type="file">` :
2019-03-17 20:05:02 +03:00
```html run
<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>
` ``
` ``smart
2019-03-20 15:09:06 +03:00
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]`.
2019-03-17 20:05:02 +03:00
` ``
## FileReader
2019-05-29 21:38:58 +03:00
[FileReader](https://www.w3.org/TR/FileAPI/#dfn-filereader) is an object with the sole purpose of reading data from ` Blob` (and hence ` File` too) objects.
2019-03-17 20:05:02 +03:00
2019-05-29 21:38:58 +03:00
It delivers the data using events, as reading from disk may take time.
2019-03-17 20:05:02 +03:00
The constructor:
` ``js
let reader = new FileReader(); // no arguments
` ``
The main methods:
2019-07-03 17:19:00 +03:00
- **` readAsArrayBuffer(blob)`** -- read the data in binary format ` ArrayBuffer`.
- **` readAsText(blob, [encoding])`** -- read the data as a text string with the given encoding (` utf-8` by default).
- **` readAsDataURL(blob)`** -- read the binary data and encode it as base64 data url.
2019-03-17 20:05:02 +03:00
- **` abort()`** -- cancel the operation.
2019-07-03 17:19:00 +03:00
The choice of ` read*` method depends on which format we prefer, how we're going to use the data.
2019-07-04 18:13:00 +03:00
- ` readAsArrayBuffer` - for binary files, to do low-level binary operations. For high-level operations, like slicing, ` File` inherits from ` Blob`, so we can call them directly, without reading.
2019-07-03 17:19:00 +03:00
- ` readAsText` - for text files, when we'd like to get a string.
- ` readAsDataURL` -- when we'd like to use this data in ` src` for ` img` or another tag. There's an alternative to reading a file for that, as discussed in chapter <info:blob>: ` URL.createObjectURL(file)`.
2019-03-17 20:05:02 +03:00
As the reading proceeds, there are events:
- ` loadstart` -- loading started.
- ` progress` -- occurs during reading.
- ` load` -- no errors, reading complete.
- ` abort` -- ` abort()` called.
2019-05-29 20:03:39 +03:00
- ` error` -- error has occurred.
2019-03-17 20:05:02 +03:00
- ` loadend` -- reading finished with either success or failure.
2019-03-20 15:09:06 +03:00
When the reading is finished, we can access the result as:
2019-03-17 20:05:02 +03:00
- ` 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`.
2019-03-20 15:09:06 +03:00
Here's an example of reading a file:
2019-03-17 20:05:02 +03:00
` ``html run
<input type="file" onchange="readFile(this)">
<script>
function readFile(input) {
let file = input.files[0];
let reader = new FileReader();
2019-03-20 15:09:06 +03:00
reader.readAsText(file);
2019-03-17 20:05:02 +03:00
reader.onload = function() {
console.log(reader.result);
};
reader.onerror = function() {
console.log(reader.error);
};
}
</script>
` ``
2019-03-20 15:09:06 +03:00
` ``smart header="` FileReader` for blobs"
2019-07-03 17:19:00 +03:00
As mentioned in the chapter <info:blob>, ` FileReader` can read not just files, but any blobs.
2019-03-20 15:09:06 +03:00
2019-07-03 17:19:00 +03:00
We can use it to convert a blob to another format:
2019-03-20 15:09:06 +03:00
- ` readAsArrayBuffer(blob)` -- to ` ArrayBuffer`,
- ` readAsText(blob, [encoding])` -- to string (an alternative to ` TextDecoder`),
- ` readAsDataURL(blob)` -- to base64 data url.
` ``
2019-03-17 20:05:02 +03:00
2019-07-03 17:19:00 +03:00
` ``smart header="` FileReaderSync` is available inside Web Workers"
2019-03-17 20:05:02 +03:00
For Web Workers, there also exists a synchronous variant of ` FileReader`, called [FileReaderSync](https://www.w3.org/TR/FileAPI/#FileReaderSync).
2019-03-20 15:09:06 +03:00
Its reading methods ` read*` do not generate events, but rather return a result, as regular functions do.
2019-03-17 20:05:02 +03:00
2019-05-29 21:38:58 +03:00
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.
2019-03-17 20:05:02 +03:00
` ``
2019-03-18 11:36:08 +03:00
## Summary
2019-03-17 20:05:02 +03:00
2019-04-30 08:57:48 -04:00
` File` objects inherit from ` Blob`.
2019-03-18 11:36:08 +03:00
2019-07-03 17:19:00 +03:00
In addition to ` Blob` methods and properties, ` File` objects also have ` name` 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 events (` ondragend`).
2019-03-18 11:36:08 +03:00
` 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`).
2019-03-20 15:09:06 +03:00
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.
2019-03-18 11:36:08 +03:00
2019-07-03 17:19:00 +03:00
And if we're going to send a ` File` over a network, that's also easy: network API like ` XMLHttpRequest` or ` fetch` natively accepts ` File` objects.