-
-
Save john-doherty/6a9bf0f6b5eb77fb2bd332571a84c7c2 to your computer and use it in GitHub Desktop.
var fileStorage = { | |
/** | |
* Saves a file on the device | |
* @param {string} name - filename (can include sub folders) | |
* @param {string} data - file contents | |
* @param {boolean} useSandbox - uses protected sandbox if true, otherwise external (default false) | |
* @returns {Promise} executes .then with saved file path as first param | |
*/ | |
write: function (name, data, useSandbox) { | |
var nameParts = name.split('/'); | |
var nameIndex = 0; | |
var dir = (useSandbox) ? cordova.file.dataDirectory : cordova.file.externalDataDirectory; | |
return new Promise(function (resolve, reject) { | |
var fail = function (msg, error) { | |
reject('Write failed on ' + msg + ', code: ' + error.code); | |
}; | |
var fileUrl = ''; | |
var gotFileWriter = function (writer) { | |
writer.onwrite = function () { | |
resolve(fileUrl); | |
//resolve(writer.localURL); | |
}; | |
writer.onerror = fail.bind(null, 'gotFileWriter'); | |
writer.write(data); | |
}; | |
var gotFileEntry = function (fileEntry) { | |
fileUrl = fileEntry.toURL(); | |
fileEntry.createWriter(gotFileWriter, fail.bind(null, 'createWriter')); | |
}; | |
var gotDirectory = function (directory) { | |
nameIndex++; | |
if (nameIndex === (nameParts.length - 1)) { | |
directory.getFile(nameParts[nameIndex], { create: true, exclusive: false }, gotFileEntry, fail.bind(null, 'gotDirectory - getDirectory')); | |
} | |
else { | |
directory.getDirectory(nameParts[nameIndex], { create: true }, gotDirectory, fail.bind(null, 'gotDirectory - getFile')); | |
} | |
}; | |
var gotFileSystem = function (fileSystem) { | |
if (nameParts.length > 1) { | |
fileSystem.getDirectory(nameParts[nameIndex], { create: true }, gotDirectory, fail.bind(null, 'gotFileSystem - getDirectory')); | |
} | |
else { | |
fileSystem.getFile(name, { create: true, exclusive: false }, gotFileEntry, fail.bind(null, 'gotFileSystem - getFile')); | |
} | |
}; | |
window.resolveLocalFileSystemURL(dir, gotFileSystem, fail.bind(null, 'requestFileSystem')); | |
}); | |
}, | |
/** | |
* Reads a file from the device | |
* @param {string} name - filename (can include sub folders) | |
* @param {boolean} useSandbox - uses protected sandbox if true, otherwise external (default false) | |
* @returns {Promise} executes .then with file content as first param | |
*/ | |
read: function (name, useSandbox) { | |
var dir = (useSandbox) ? cordova.file.dataDirectory : cordova.file.externalDataDirectory; | |
return new Promise(function (resolve, reject) { | |
var fail = function (msg, error) { | |
reject('Read failed on ' + msg + ', code: ' + error.code); | |
}; | |
var gotFile = function (file) { | |
var reader = new FileReader(); | |
reader.onloadend = function (evt) { | |
resolve(evt.target.result); | |
}; | |
reader.onerror = fail.bind(null, 'gotFile'); | |
reader.readAsText(file); | |
}; | |
var gotFileEntry = function (fileEntry) { | |
fileEntry.file(gotFile, fail.bind(null, 'gotFileEntry')); | |
}; | |
window.resolveLocalFileSystemURL(dir + name, gotFileEntry, fail.bind(null, 'resolveLocalFileSystemURL')); | |
}); | |
}, | |
/** | |
* Removes a file from the device | |
* @param {string} name - filename (can include sub folders) | |
* @param {boolean} useSandbox - uses protected sandbox if true, otherwise external (default false) | |
* @returns {Promise} .then is executed if successful otherwise .catch with error message | |
*/ | |
removeFile: function (name, useSandbox) { | |
var dir = (useSandbox) ? cordova.file.dataDirectory : cordova.file.externalDataDirectory; | |
return new Promise(function (resolve, reject) { | |
var fail = function (msg, error) { | |
reject('Remove file failed on ' + msg + ', code: ' + error.code); | |
}; | |
var gotFileEntry = function (fileEntry) { | |
fileEntry.remove(function () { | |
resolve(); | |
}, fail.bind(null, 'remove')); | |
}; | |
window.resolveLocalFileSystemURL(dir + name, gotFileEntry, fail.bind(null, 'resolveLocalFileSystemURL')); | |
}); | |
}, | |
/** | |
* Removes an entire directory from the device | |
* @param {string} name - directory name/path to remove | |
* @param {boolean} useSandbox - uses protected sandbox if true, otherwise external (default false) | |
* @returns {Promise} .then is executed if successful otherwise .catch with error message | |
*/ | |
removeDirectory: function (name, useSandbox) { | |
var dir = (useSandbox) ? cordova.file.dataDirectory : cordova.file.externalDataDirectory; | |
return new Promise(function (resolve, reject) { | |
var fail = function (msg, error) { | |
reject('Remove directory failed on ' + msg + ', code: ' + error.code); | |
}; | |
var gotDirectory = function (directory) { | |
directory.removeRecursively(function () { | |
resolve(); | |
}, fail.bind(null, 'removeRecursively')); | |
}; | |
window.resolveLocalFileSystemURL(dir + name, gotDirectory, fail.bind(null, 'resolveLocalFileSystemURL')); | |
}); | |
} | |
}; |
This will use external (unprotected storage) by default, set useSandbox
to true to save files in a protected location where users and external app are unable to access them.
You should convert this to a proper repository, there is some good stuff here that others should be able to find a lot easier.
Good point @drannex42, I've created a repo cordova-file-storage. Let me know if you have any suggestions/tweaks.
Im getting an error whenever I try to read a file. "Read failed on resolveLocalFileSystemURL, code: 1"
I was able to write the file with/without sandbox , I can see the file in the emulator but whenever I try to read it I get that error.
I have add this in confix.xml
also on AndroidManifest.xml
Don't know if I have to do add anything else
Here is a quick example of how to use the singleton above to write files: