File and FileReader
A File is a specialized kind of Blob. It carries all the binary machinery a Blob has, then adds the two things a real filesystem entry needs: a name and a “last modified” timestamp. Because File sits on top of Blob, everything you already know about blobs — size, type, slice() — works on a File unchanged.
Two ways to get a File
One: the constructor. It mirrors the Blob constructor but takes a name in the middle:
new File(fileParts, fileName, [options])
fileParts— an array ofBlob,BufferSource, orStringvalues, the same shape you’d pass tonew Blob([...]).fileName— the file name, as a string.options— optional object:lastModified— the timestamp (an integer date) of the last modification.
You’d build a File by hand when you generate content in the browser — say, exporting a canvas or bundling text — and want to hand it to code that expects a real file, like a fetch upload.
Two: the browser hands you one. This is the common case. When a user picks a file through <input type="file">, drops one onto the page, or pastes an image, the browser creates the File for you and fills in name and lastModified from the operating system. You don’t set those values; they describe the actual file on the user’s disk.
Since File inherits from Blob, a File object has every Blob property, plus:
name— the file name.lastModified— the timestamp of the last modification.
Here’s how you read a File out of an <input type="file">:
<input type="file" onchange="inspectFile(this)">
<script>
function inspectFile(input) {
let file = input.files[0];
alert(`File name: ${file.name}`); // e.g. quarterly-report.pdf
alert(`Last modified: ${file.lastModified}`); // e.g. 1699887654321
}
</script>
FileReader
FileReader exists to do one job: pull data out of a Blob (and therefore out of a File, which is a Blob). It doesn’t create files or write them — it reads.
Reading from disk can take real time, so FileReader doesn’t block and return a value. It works asynchronously and reports back through events. You kick off a read, then wait for the browser to tell you it’s done.
The constructor takes nothing:
let reader = new FileReader(); // no arguments
The read methods
Each method starts a read and produces the result in a particular format:
readAsArrayBuffer(blob)— read the raw bytes into anArrayBuffer.readAsText(blob, [encoding])— decode the bytes into a string using the given encoding (utf-8by default).readAsDataURL(blob)— read the bytes and encode them as a base64data:URL.abort()— stop a read that’s in progress.
Which one you pick comes down to how you plan to use the data:
readAsArrayBuffer— for binary files where you need byte-level access. If you only want high-level operations like slicing, you don’t need to read at all:Fileinheritsslice()fromBlob, so you can call it directly.readAsText— for text files, when you want a plain string back.readAsDataURL— when the data goes straight into asrc, like an<img>or<a>. There’s a lighter alternative for that specific case —URL.createObjectURL(file), covered in the Blob chapter — which hands you a URL without decoding the whole file into base64.
The events
As a read proceeds, FileReader fires events in order:
loadstart— reading has started.progress— fired periodically while reading.load— reading completed with no error.abort—abort()was called.error— an error occurred.loadend— reading finished, whether it succeeded or failed.
Once a read finishes, two properties hold the outcome:
reader.result— the result, on success.reader.error— the error, on failure.
In practice you’ll wire up load and error far more than the rest.
Here’s a full read of a text 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>
Summary
File objects inherit from Blob.
On top of the Blob methods and properties, a File adds name and lastModified, plus the built-in ability to read from the filesystem. You most often get File objects from user input — an <input> or drag-and-drop events (ondragend).
FileReader reads a file or a blob into one of three formats:
- String —
readAsText. ArrayBuffer—readAsArrayBuffer.- Base64 data URL —
readAsDataURL.
Often you don’t need to read the contents at all. As with blobs, you can mint a short URL with URL.createObjectURL(file) and assign it to an <a> or <img> — the file downloads, shows as an image, feeds a canvas, and so on.
And sending a File over the network is straightforward: APIs like XMLHttpRequest and fetch accept File objects natively.