Author
The FileSystem API and File API, a web application can create, read, view and write files and/or directories in a virtual, sandboxed file system.
The file and directory API is an important programming interface for the following reasons:
Applications with continuous loading.
Video games or other applications with a lot of media resources.
Audio or photo editor with the ability to work offline or a local cache.
Offline video player.
Offline email client.
In this table first row is browser, the second is version
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
13 | ≤18 | 50 | No | 15 | 11.1 |
*Today only Chrome has a full support of FileSystem API
File - allows you to get such read-only information as name, size, mimetype and more.
FileList - "array" of File objects.
Blob - an entity that allows you to parse a file by bytes.
The asynchronous API should be used for most operations, to prevent file system accesses from blocking the entire browser if used on the main thread. It includes the following interfaces:
The synchronous API is should only be used in Workers; these calls block until they're finished executing, and simply return the results instead of using callbacks. Using them on the main thread will block the browser, which is naughty. The interfaces below otherwise mirror the ones from the asynchronous API.
Gives you access to a sandboxed file system.
You can request access to a sandboxed file system by requesting LocalFileSystemSync object from within a web worker.
Provides tools to deal with a given file with all the necessary locks.
The Metadata interface is used by the File and Directory Entries API to contain information about a file system entry. This metadata includes the file's size and modification date and time.
In this presentation we will look at the asynchronous version of the API
Get access to the HTML5 file system by making a request to the LocalFile system object using the global window.requestFileSystem () method:
window.requestFileSystem(type, size, successCallback, opt_errorCallback);
Example:
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
window.requestFileSystem(window.TEMPORARY, 5*1024*1024, initFS, errorHandler);
function initFS(fs){
alert("Welcome to Filesystem! It's showtime"); // Just to check if everything is OK
}
function errorHandler(){
console.log('An error occured');
}
Persistent storage - is storage that stays in the browser unless the user expunges it or the app deletes it.
Temporary storage - Transient storage is available to any web app. It is automatic and does not need to be requested, but the browser can delete the storage without warning.
The size (in bytes) of storage that the application will need.
Callback function executed in case of successful access to the file system. Its argument is an object of type FileSystem.
Optional callback function for handling errors. It is also called when file system access errors occur. The parameter is an object of type FileError.
The first thing to create in the file system is memory chunks, or directories. Although the root folder already exists, you do not need to put all the files there. Directories are created by a DirectoryEntry. In the following example, we create a directory called Documents inside the root folder:
fs.root.getDirectory('Documents', {create: true}, function(dirEntry) {
alert('You have just created the ' + dirEntry.name + ' directory.');
}, errorHandler);
The getDirectory () method is used both for reading and creating a directory. As the first parameter, you can pass the name or route as a directory for searching or creating. If you need to create a directory, then the second parameter is true.
Now it's time to see what is in our file system. Create a DirectoryReader object and use the readEntries () method to read the contents of a directory.
fs.root.getDirectory('Documents', {}, function(dirEntry){
var dirReader = dirEntry.createReader();
dirReader.readEntries(function(entries) {
for(var i = 0; i <= entries.length; i++) {
var entry = entries[i];
if (entry.isDirectory){
console.log('Directory: ' + entry.fullPath);
}
else if (entry.isFile){
console.log('File: ' + entry.fullPath);
}
}
}, errorHandler);
}, errorHandler);
The isDirectory and isFile properties are used to respectively obtain different output of directories and files. In addition, we use the fullPath property to get the full entry route instead of just one name.
There are two ways to remove DirectoryEntry from the file system: remove () and removeRecursively (). The first one deletes this folder only if it is empty. Otherwise, you will get an error.
fs.root.getDirectory('Documents/Music', {}, function(dirEntry) {
dirEntry.remove(function(){
console.log('Directory successfully removed.');
}, errorHandler);
}, errorHandler);
If there are files inside the Music folder, then you will need to apply the second method, which recursively deletes the folder and all its contents.
fs.root.getDirectory('Documents/Music', {}, function(dirEntry) {
dirEntry.removeRecursively(function(){
console.log('Directory successufully removed.');
}, errorHandler);
}, errorHandler);
The following example creates an empty test.txt in the root folder:
fs.root.getFile('test.txt', {create: true, exclusive: true}, function(fileEntry) {
alert('A file ' + fileEntry.name + ' was created successfully.');
}, errorHandler);
We extract the test.txt file and create a FileWriter object for it. Then we attach the contents to it, creating a new BlobBuilder object and applying the write () method to FileWriter.
fs.root.getFile('test.txt', {}, function(fileEntry) {
fileEntry.file(function(file) {
var reader = new FileReader();
reader.onloadend = function(e) {
alert(this.result);
};
reader.readAsText(file);
}, errorHandler);
}, errorHandler);
You can rearrange the application to write to the end of the file using the seek () method. seek takes an offset in bytes as an argument and sets the location of the application to write to files for this offset.
fs.root.getFile('test.txt', {create: false}, function(fileEntry) {
fileEntry.createWriter(function(fileWriter) {
fileWriter.seek(fileWriter.length);
window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder;
var bb = new BlobBuilder();
bb.append('Yes, it is!');
fileWriter.write(bb.getBlob('text/plain'));
}, errorHandler);
}, errorHandler);
To remove a file from the system, simply call entry.remove (). The first argument to this method is a callback function with a null parameter, which is called when the file is successfully deleted. The second is a random error callback.
fs.root.getFile('test.txt', {create: false}, function(fileEntry) {
fileEntry.remove(function() {
console.log('File successufully removed.');
}, errorHandler);
}, errorHandler);
FileEntry and DirectoryEntry share the same methods of copying the API, moving and renaming inputs. Two methods can be used for these operations: copyTo () and moveTo (). They both take the same parameters:
copyTo(parentDirEntry, opt_newName, opt_successCallback, opt_errorCallback);
moveTo(parentDirEntry, opt_newName, opt_successCallback, opt_errorCallback);
The first parameter is the parent folder for moving / copying input to it. The second is an arbitrary new name given to the moved / copied input, which is actually required when you copy the input in the same folder, otherwise you will have an error. The third and fourth parameters were explained earlier.
Let's see some examples. Copy the test.txt file from root to the Documents directory.
function copy(currDir, srcEntry, destDir) {
currDir.getFile(srcEntry, {}, function(fileEntry) {
currDir.getDirectory(destDir, {}, function(dirEntry) {
fileEntry.copyTo(dirEntry);
}, errorHandler);
}, errorHandler);
}
copy(fs.root, 'test.txt', 'Documents/');
Moving .txt to Documents:
function move(currDir, srcEntry, dirName) {
currDir.getFile(srcEntry, {}, function(fileEntry) {
currDir.getDirectory(dirName, {}, function(dirEntry) {
fileEntry.moveTo(dirEntry);
}, errorHandler);
}, errorHandler);
}
move(fs.root, 'test.txt', 'Documents/');
Rename test.txt into text.txt
function rename(currDir, srcEntry, newName) {
currDir.getFile(srcEntry, {}, function(fileEntry) {
fileEntry.moveTo(currDir, newName);
}, errorHandler);
}
rename(fs.root, 'test.txt', 'text.txt');
For a deeper study of FileSystem API you can use the following links on W3C:
The file system API is a powerful and easy-to-use technology that provides web developers with a host of new features when building web applications. This technology is still fairly new and not widely supported by major browsers.