Skip to content

PhoneGap Cordova File System FAQ

Raymond Camden edited this page Aug 18, 2014 · 4 revisions

When does it make sense to use the file system (versus LocalStorage or WebSQL)?

First - remember that storing data locally is something you should consider when building any application. Data can be slow to transfer to the end user. The end user may be offline. Data may be static and not change often. There's a variety of reasons why you should consider ensuring you only download data once, or only once in a while at minimum.

A Cordova application can store data locally in a variety of ways: Local Storage, Web SQL, IndexedDB (only in very recent browsers though), and the File System. So when would the file system make sense?

While there aren't strict rules on when you would use one over the other, in general, the guidelines I follow for storage are as follows:d

Local Storage is useful for simple key/value type storage. For example, storing the user's username, their favorite color. You can store a lot of data in Local Storage, but in general I tend to use it mainly for preferences.

WebSQL (and IndexedDB) are better for ad hoc, user-created style content. So for example, if the application lets the user take notes, then WebSQL would be more preferable. It is easier to search and aggregate large sets of data with WebSQL versus Local Storage.

But where both Local Storage and Web SQL are good at storing data, binary data and files make more sense on the file system. You can encode binary data in Base64, but that can be an expensive process. Since you do have a file system available to you, it makes sense to make use of it for file based data.

How do I download an asset to my application?

You can download assets to your application two ways. The first way is via the typical AJAX request. Any AJAX request that returns data can be used to fetch data that can then be written to the file system using the File System API. Modern browsers can handle binary data, but this technique is typically used for text files.

The preferred way to download an asset would be to make use of the File Transfer API. The download method of the File Transfer API will let you easily grab a file of any form and save it to the local file system. It has callbacks for successful and errored results as well as an onprogress event that can be used to monitor how much data has been sent. You can also abort an existing transfer.

Reference: https://github.com/apache/cordova-plugin-file-transfer/blob/master/doc/index.md How do I use a file stored in the file system (both binary and text-based files)? It depends on what you mean by "use" of course. Let's look at a few simple examples.

How do I check to see if a file exists in a directory?

The function, window.resolveLocalFileSystemURL, is a simple way to do this. It takes three arguments: The path, the success function, and the error handler. The error handler would be thrown if the file does not exist. Here is a concrete example:

window.resolveLocalFileSystemURL(cordova.file.dataDirectory + "foo.txt", fileExisted, fileDidNotExist);

How can I get metadata (size, updated) about a file?

The fileEntry object has a file method. That method is passed a file object that includes keys for size and lastModified values (along with others keys an a slice method). Here is a full example.

document.addEventListener("deviceready", init, false);
function init() {

//This alias is a read-only pointer to the app itself
window.resolveLocalFileSystemURL(cordova.file.applicationDirectory + "www/index.html", gotFile, fail);

}

function fail(e) {
console.log("FileSystem Error");
console.dir(e);
}

function gotFile(fileEntry) {

fileEntry.file(function(file) {
	var s = "";
	s += "<b>name:</b> " + file.name + "<br/>";
	s += "<b>localURL:</b> " + file.localURL + "<br/>";
	s += "<b>type:</b> " + file.type + "<br/>";
	s += "<b>lastModifiedDate:</b> " + (new Date(file.lastModifiedDate)) + "<br/>";
	s += "<b>size:</b> " + file.size + "<br/>";
	
	document.querySelector("#status").innerHTML = s;
	console.dir(file);
});
}

You can find a full demo of this here.