Skip to content

Instantly share code, notes, and snippets.

@brickpop
Last active August 29, 2015 14:02
Show Gist options
  • Save brickpop/78551f439578f7c132c8 to your computer and use it in GitHub Desktop.
Save brickpop/78551f439578f7c132c8 to your computer and use it in GitHub Desktop.
Phonegap File API JS Wrapper
// Wrapping of the example found on https://gist.github.com/alunny/1904992
// Jordi Moraleda
// This example works on org.apache.cordova.file version 1.1.0 and 1.2.0
//
// If you are using version 1.3.0, check out the file below
// https://gist.github.com/jmoraleda/78551f439578f7c132c8#file-fswrapper-v1-3-js
function FSWrapper(options, callback) {
var self = this;
function fail(e) {
if(typeof callback == "function")
callback(null, {error: e});
else
throw new Error();
}
function gotFS(fs) {
self.fs = fs.filesystem;
self.fs.root.getDirectory("AppFiles", {create: true, exclusive: false}, function(){
self.fs.root.getDirectory(self.folderPrefix, {create: true, exclusive: false}, function(){
if(typeof callback == "function")
callback(fs);
else
throw new Error();
}, fail);
}, fail);
}
if(typeof options == "function") { // Si només hi ha un paràmetre...
callback = options;
options = {};
}
if(options && options.folderPrefix) {
this.folderPrefix = "AppFiles/" + options.folderPrefix;
}
else {
this.folderPrefix = "AppFiles/" + applicationParameters.docFolderName;
}
setTimeout(function(){
window.resolveLocalFileSystemURL(cordova.file.dataDirectory, gotFS, fail);
});
return this;
}
// READ A FILE
FSWrapper.prototype.read = function(filename, callback) {
var self = this;
self.filename = filename;
self.file = {
writer: { },
reader: { }
};
function fail(e) {
if(typeof callback == "function")
callback(null, {error: e});
}
function gotFileEntry(fileEntry) {
self.file.entry = fileEntry;
self.file.entry.file(function (rFile) {
var reader = new FileReader();
reader.onerror = fail;
reader.onloadend = function (evt) {
if(typeof callback == "function")
callback(evt.target.result, evt.target.error);
}
reader.readAsText(rFile);
}, fail);
}
self.fs.root.getFile(self.folderPrefix + "/" + self.filename, {create: true, exclusive: false}, gotFileEntry, fail);
};
// WRITE TO A FILE
FSWrapper.prototype.write = function(filename, content, callback) {
var self = this;
self.filename = filename;
self.file = {
writer: { },
reader: { }
};
function fail(e) {
if(typeof callback == "function")
callback(null, {error: e});
}
function gotFileWriter(fw) {
self.file.writer.object = fw;
self.file.writer.object.onerror = fail;
self.file.writer.object.onwriteend = function (evt) {
if(typeof callback == "function")
callback(evt);
}
self.file.writer.object.write(content);
}
function gotFileEntry(fileEntry) {
self.file.entry = fileEntry;
self.file.entry.createWriter(gotFileWriter, fail);
}
self.fs.root.getFile(self.folderPrefix + "/" + self.filename, {create: true, exclusive: false}, gotFileEntry, fail);
};
// REMOVE A FILE (OR AN EMPTY FOLDER)
FSWrapper.prototype.remove = function(filename, callback) {
var self = this;
self.filename = filename;
function fail(e) {
if(typeof callback == "function")
callback(null, {error: e});
}
function gotFileEntry(fileEntry) {
fileEntry.remove(callback, fail);
}
self.fs.root.getFile(self.folderPrefix + "/" + self.filename, {exclusive: false}, gotFileEntry, fail);
};
// REMOVE A FOLDER
FSWrapper.prototype.removeDirectory = function(folderName, callback) {
var self = this;
self.filename = folderName;
function fail(e) {
if(typeof callback == "function")
callback(null, {error: e});
}
function gotDirectoryEntry(directoryEntry) {
directoryEntry.removeRecursively(callback, fail);
}
self.fs.root.getDirectory(self.folderPrefix + "/" + folderName, {exclusive: false}, gotDirectoryEntry, fail);
};
// GET A FILE ENTRY
FSWrapper.prototype.getFile = function(filename, callback) {
var self = this;
self.filename = filename;
function fail(e) {
if(typeof callback == "function")
callback(null, {error: e});
}
function gotFileEntry(fileEntry) {
self.fileEntry = fileEntry;
if(typeof callback == "function")
callback(self.fileEntry);
}
self.fs.root.getFile(self.folderPrefix + "/" + self.filename, {create: true, exclusive: false}, gotFileEntry, fail);
};
// GET (OR CREATE) A FOLDER
FSWrapper.prototype.getDirectory = function(dirname, callback) {
var self = this;
self.filename = dirname;
function fail(e) {
if(typeof callback == "function")
callback(null, {error: e});
else
throw new Error("Unable to get the directory: " + dirname);
}
function gotDirectory(dirEntry) {
if(typeof callback == "function")
callback(dirEntry);
}
self.fs.root.getDirectory(self.folderPrefix + "/" + dirname, {create: true}, gotDirectory, fail);
};
// CREATE A FOLDER
FSWrapper.prototype.createDirectory = function(dirname, callback) {
var self = this;
dirname = self.folderPrefix + "/" + dirname;
var dirs = dirname.split("/").reverse();
var root = self.fs.root;
var createDir = function(dir){
root.getDirectory(dir, {
create : true,
exclusive : false
}, gotDirectory, fail);
};
var gotDirectory = function(dirEntry){
root = dirEntry;
if(dirs.length > 0){
createDir(dirs.pop());
}else{
if(typeof callback == "function")
callback(dirEntry);
}
};
var fail = function(e){
if(typeof callback == "function")
callback(null, {error: e});
};
createDir(dirs.pop());
};
// LIST THE CONTENTS OF A FOLDER
FSWrapper.prototype.listDirectory = function(dirname, callback) {
var self = this;
self.filename = dirname;
function fail(e) {
if(typeof callback == "function")
callback(null, {error: e});
}
function gotDirectory(dirEntry) {
var dirReader = dirEntry.createReader();
dirReader.readEntries (function(results) {
if(typeof callback == "function")
callback(results);
}, fail);
}
self.fs.root.getDirectory(self.folderPrefix + "/" + dirname, {create: true}, gotDirectory, fail);
};
// NOTE: org.apache.cordova.file-transfer is necessary to use this function
FSWrapper.prototype.download = function(url, filePath, callback){
var fileTransfer = new FileTransfer();
var uri = encodeURI(url);
var target = this.fs.root.toURL() + this.folderPrefix + '/' + filePath;
// Fix for plugin file@1.2.0 => As of org.apache.cordova.file@1.3.0 the problem is no longer there
// if(device.platform == "iOS") {
// if(target.indexOf("file://localhost") === 0) {
// target = target.substr(16); // Trick for iOS 6
// }
// else if(target.indexOf("file://") === 0) {
// target = target.substr(7); // Trick for iOS 7
// }
// }
fileTransfer.download(
uri,
target,
function(entry) {
callback(entry);
},
function(error) {
callback(null, error);
},
false,
{ }
);
};
// Usage Example
var fswrapper = new FSWrapper(function(){
fswrapper.write("filename.txt", "Some contents", function(writeEndEvent, error){
if(error)
console.log("ERROR: " + JSON.stringify(error));
else
console.log("DONE");
file.read("filename.txt", function(contents, error){
console.log(contents, error);
});
});
});
///////////////////////////////////////////////////////////////////////////////
// FILESYSTEM API WRAPPER
// Jordi Moraleda
//
function FSWrapper(a,b) {
var self = this;
self.folderPrefix = "AppFiles/" + applicationParameters.docFolderName;
self.init = function(doneCallback, errCallback){
window.resolveLocalFileSystemURL(cordova.file.dataDirectory, doneCallback, errCallback);
};
if(typeof a == "function") setTimeout(a,10); // Temp compatibility
else if(typeof b == "function") setTimeout(b,10)
return this;
}
// READ A FILE
FSWrapper.prototype.read = function(filename, callback) {
this.init(function(rootEntry) {
rootEntry.getFile(filename, {create: true, exclusive: false}, gotFileEntry, fail);
}, function(err){
if(typeof callback == "function")
callback(null, {error: err});
});
function fail(e) {
if(typeof callback == "function")
callback(null, {error: e});
}
function gotFileEntry(fileEntry) {
fileEntry.file(function (rFile) {
var reader = new FileReader();
reader.onerror = fail;
reader.onloadend = function (evt) {
if(typeof callback == "function")
callback(evt.target.result, evt.target.error);
}
reader.readAsText(rFile);
}, fail);
}
};
// WRITE TO A FILE
FSWrapper.prototype.write = function(filename, content, callback) {
this.init(function(rootEntry) {
rootEntry.getFile(filename, {create: true, exclusive: false}, gotFileEntry, fail);
}, function(err){
if(typeof callback == "function")
callback(null, {error: err});
});
function fail(e) {
if(typeof callback == "function")
callback(null, {error: e});
}
function gotFileEntry(fileEntry) {
fileEntry.createWriter(gotFileWriter, fail);
}
function gotFileWriter(fw) {
fw.onerror = fail;
fw.onwriteend = function (evt) {
if(typeof callback == "function")
callback(evt);
}
fw.write(content);
}
};
// REMOVE A FILE (OR AN EMPTY FOLDER)
FSWrapper.prototype.remove = function(filename, callback) {
this.init(function(rootEntry) {
rootEntry.getFile(filename, {create: true, exclusive: false}, gotFileEntry, fail);
}, function(err){
if(typeof callback == "function")
callback(null, {error: err});
});
function fail(e) {
if(typeof callback == "function")
callback(null, {error: e});
}
function gotFileEntry(fileEntry) {
fileEntry.remove(callback, fail);
}
};
// REMOVE A FOLDER
FSWrapper.prototype.removeDirectory = function(folderName, callback) {
this.init(function(rootEntry) {
rootEntry.getFile(folderName, {create: true, exclusive: false}, gotDirectoryEntry, fail);
}, function(err){
if(typeof callback == "function")
callback(null, {error: err});
});
function fail(e) {
if(typeof callback == "function")
callback(null, {error: e});
}
function gotDirectoryEntry(directoryEntry) {
directoryEntry.removeRecursively(callback, fail);
}
};
// GET A FILE ENTRY
FSWrapper.prototype.getFile = function(filename, callback) {
this.init(function(rootEntry) {
rootEntry.getFile(filename, {create: true, exclusive: false}, gotFileEntry, fail);
}, function(err){
if(typeof callback == "function")
callback(null, {error: err});
});
function fail(e) {
if(typeof callback == "function")
callback(null, {error: e});
}
function gotFileEntry(fileEntry) {
if(typeof callback == "function")
callback(fileEntry);
}
};
// GET (OR CREATE) A FOLDER
FSWrapper.prototype.getDirectory = function(dirname, callback) {
this.init(function(rootEntry) {
rootEntry.getFile(dirname, {create: true, exclusive: false}, gotDirectoryEntry, fail);
}, function(err){
if(typeof callback == "function")
callback(null, {error: err});
});
function fail(e) {
if(typeof callback == "function")
callback(null, {error: e});
}
function gotDirectoryEntry(dirEntry) {
if(typeof callback == "function")
callback(dirEntry);
}
};
// CREATE A FOLDER
FSWrapper.prototype.createDirectory = function(dirname, callback) {
var self = this;
var dirs = dirname.split("/").reverse();
this.init(function(rootEntry) {
self.rootEntry = rootEntry;
createDir(dirs.pop());
}, function(err){
if(typeof callback == "function")
callback(null, {error: err});
});
function createDir(dir){
self.rootEntry.getDirectory(dir, {
create : true,
exclusive : false
}, gotDirectoryEntry, fail);
}
function gotDirectoryEntry(dirEntry){
root = dirEntry;
if(dirs.length > 0){ // continuar
createDir(dirs.pop());
} else { // Done
if(typeof callback == "function")
callback(dirEntry);
}
}
function fail(e){
if(typeof callback == "function")
callback(null, {error: e});
}
};
// LIST THE CONTENTS OF A FOLDER
FSWrapper.prototype.listDirectory = function(dirname, callback) {
this.init(function(rootEntry) {
rootEntry.getFile(dirname, {create: true, exclusive: false}, gotDirectoryEntry, fail);
}, function(err){
if(typeof callback == "function")
callback(null, {error: err});
});
function fail(e) {
if(typeof callback == "function")
callback(null, {error: e});
}
function gotDirectoryEntry(dirEntry) {
var dirReader = dirEntry.createReader();
dirReader.readEntries (function(results) {
if(typeof callback == "function")
callback(results);
}, fail);
}
};
FSWrapper.prototype.download = function(url, filePath, callback){
this.init(function(rootEntry) {
var fileTransfer = new FileTransfer();
var uri = encodeURI(url);
var target = rootEntry.toURL() + filePath;
fileTransfer.download(uri, target,
function(entry) {
callback(entry);
},
function(error) {
callback(null, error);
},
applicationParameters.acceptAllSSL,
{ }
);
}, function(err){
if(typeof callback == "function")
callback(null, {error: err});
});
};
@cloud1250x4
Copy link

is it possible to add a delete option? Also, does it works with phonegap 3.5? How can I get the path of the file?

@cloud1250x4
Copy link

I tried something like this

var file = new FSWrapper("video.m3u8");
file.write(videourl, function(e){
file.read(function(result, error){VideoPlayer.play("file:///video.m3u8")});
});

but it doesn't work , have you any idea what's the location of the file?

@brickpop
Copy link
Author

Hi cloud1250000. Sorry I didn't see your message before. I've updated the contents with a rather different version.

There is a function called removeFolder(folderName, callback). Check it out, as well as the R/W example at the bottom of the file.

As for the problem you mention:

  • The path you are using to read the file is incorrect (file:///video.m3u8). You should use the getFile(fileName, callback) function. The callback will provide you with a FileEntry object. You can get the nativeURL property of it and pass it to the video reader.
  • If you need to download a file from a remote host, use the download(url, file, callback) function. write(filename, contents, callback) is not meant to receive a URL, but data.
  • Make sure to install the org.apache.cordova.file-transfer plugin if so.
  • The new version I've copied needs the file name on each call, rather than just the filename once when you instantiate FSWrapper. See the examples.
  • Make sure to use the last version of org.apache.cordova.file (currently 1.3.0 => 1.2 broke the app when combined with org.apache.cordova.media).

Hope it helps

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment