Cordova File System Access
Beyond simple key-value storage, some apps need real files — saving a downloaded document,
writing a log, caching a large dataset, or exporting user-generated content. The File plugin,
cordova-plugin-file, gives your JavaScript code access to the device's file
system, but through a deliberately sandboxed model rather than free rein over device storage.
This page covers that model, the directories you're given, and full worked examples for
writing and reading a text file.
Installing the Plugin
cordova plugin add cordova-plugin-file
The Sandboxed File System Model
Modern mobile operating systems don't let apps read and write arbitrary files anywhere on the device — that would be a serious privacy and security risk. Instead, each app is given its own private, isolated area of storage, plus a few specific shared locations it can request access to. The File plugin exposes this model to your JavaScript as a set of directory constants, each pointing to a URL you can use as the starting point for file operations. You don't construct these paths yourself — you ask Cordova for the right one for what you're trying to do.
Key Directory Constants
| Constant | What it points to |
|---|---|
| cordova.file.dataDirectory | Persistent, app-private storage — files here survive app restarts and are only ever cleared if the app itself deletes them or the app is uninstalled. This is the right place for data your app needs to keep long-term. |
| cordova.file.cacheDirectory | Temporary, app-private storage that the OS is allowed to clear on its own when the device is low on space — appropriate for regenerable data like thumbnails or downloaded content you can fetch again |
| cordova.file.externalRootDirectory | Android-specific: the root of external/shared storage, visible outside your app (for example, in a file manager). Requires appropriate storage permissions and is not available on iOS. |
dataDirectory by default is usually the safest choice for anything you want to keep — use cacheDirectory only for data you're fully prepared to lose without asking the user first.Full Example: Writing a Text File
Writing a file is a multi-step process: first resolve the target directory into a
DirectoryEntry, then get (or create) the specific file inside it as a
FileEntry, then open a FileWriter on that entry to actually write
content:
function writeTextFile() {
window.resolveLocalFileSystemURL(cordova.file.dataDirectory, onDirectorySuccess, onFileError);
}
function onDirectorySuccess(dirEntry) {
dirEntry.getFile('notes.txt', { create: true }, onFileGot, onFileError);
}
function onFileGot(fileEntry) {
fileEntry.createWriter(onWriterReady, onFileError);
}
function onWriterReady(writer) {
writer.onwriteend = function() {
console.log('File written successfully');
};
writer.onerror = onFileError;
writer.write('This text was saved from a Cordova app.');
}
function onFileError(error) {
console.log('File error: ' + error.code);
}
Note the { create: true } option passed to getFile() — it tells
Cordova to create the file if it doesn't exist yet, rather than failing. Passing
{ create: true, exclusive: true } instead would fail if the file already exists,
useful when you specifically want to avoid overwriting something.
Full Example: Reading a File Back
Reading a file follows a similar resolve-then-act pattern, but ends with a standard web
FileReader to actually pull the text content out of the file:
function readTextFile() {
window.resolveLocalFileSystemURL(cordova.file.dataDirectory + 'notes.txt', onReadFileEntry, onFileError);
}
function onReadFileEntry(fileEntry) {
fileEntry.file(function(file) {
var reader = new FileReader();
reader.onloadend = function() {
console.log('File contents: ' + this.result);
};
reader.onerror = onFileError;
reader.readAsText(file);
}, onFileError);
}
function onFileError(error) {
console.log('File error: ' + error.code);
}
Handling Common File Errors
The error object passed to a file error callback carries a numeric code
you can inspect to distinguish common failure cases:
| Situation | What typically happens |
|---|---|
| File not found | Calling getFile() without { create: true } on a file that doesn't exist yet fails with a "not found" error code — decide up front whether a missing file should be created or treated as a real error |
| Permission denied | Especially relevant for externalRootDirectory on Android, where the required storage permission may not have been granted by the user yet |
| Quota exceeded | Writing more data than the device has space or quota for fails with its own error code — worth handling explicitly if your app writes larger files |