Twitter: raymondcamden

Address: Lafayette, LA, USA

Cordova File System - Important Update

02-17-2014 20,571 views Mobile 76 Comments

In the past week I've gotten a few emails from folks working with the file system in PhoneGap/Cordova apps. Recently, the plugin had a major update and if you weren't paying attention to the docs/blogs, it would be easy to miss.

First, see the blog post from the Cordova site: Plugins Release: Feb 10, 2014. Second - you can get even deeper docs at the plugin Github repo docs: Docs. Finally, as the changes here were intended to bring the plugin closer to the core HTML5 FileSystem API, you should refresh your memory with the excellent HTML5Rocks article and the official spec as well.

I started up a fresh project for iOS and had no problem accessing the file system, but I didn't do anything too complex. If folks want to talk specifics, I can try to create a specific demo, but again, I strongly recommend reading the plugin doc.


These comments will soon be imported into Disqus. To add a comment, use Disqus above.
  • omid jafari #
    Commented on 02-17-2014 at 11:31 AM
    wow you helped me solve one of my biggest problems....thank you raymonnd ..brilliant would be so helpful if you could make a demo for andriod...amazing blog though:)
  • Commented on 02-17-2014 at 12:06 PM
    Do you have a specific example you would like to see?
  • Commented on 02-17-2014 at 5:00 PM
    Hello Raymond,

    Thanks for the heads-up regarding this, I would have been very confused otherwise, I'm sure!

    However, I'm running into an issue that I wonder if you might be able to shed some light on.

    I'm recording audio files using the Media plugin. After a recording has successfully completed, I want to move the file to another directory using the File plugin. Prior to the update to the File plugin, I did something like <a href=""&g...;, which worked as the filesystem root and the location that the Media plugin initially saved the recording were the same.

    Now the filesystem root is relative to my app's "private" directory (which is cool), I'm not sure how to go about reliably resolving the location of the saved recording so I can move it.

    I've tried window.resolveLocalFileSystemURL, without success thus far.

    I've also tried recording directly to the target directory (therefore removing the requirement to move the file at all), but passing targetDir.toURL() as the src param to Media doesn't seem to work.

    I'm only targeting Android, currently.

    Am I going about this the wrong way, or missing something obvious?

  • Commented on 02-17-2014 at 5:02 PM
    Oops, sorry about the mangled gist link.
  • omid jafari #
    Commented on 02-18-2014 at 5:39 AM
    yes raymond ...i wish you could make a sample demo project for android about accessing to filesystems and searching for a particular file with a specific name for example...
  • Commented on 02-18-2014 at 5:52 AM
    @omid: Well the first question is - do you know what folder you want to look in?
  • Tom #
    Commented on 02-18-2014 at 5:23 PM
    With being able to write to the internal file system now, does this improve security at all? We were looking into storing javascript files via the phonegap file api, but then realized there's the possibility of people editing those files we stored using the file api which could then inject code into our apps. Thanks for posting this tidbit!
  • omid jafari #
    Commented on 02-19-2014 at 1:35 AM
    yes presume that we know the folder..actually we make and choose this folder
  • Commented on 02-19-2014 at 9:15 AM
    @Tom: I honestly do not know. You would need to check the Android/iOS docs (not PhoneGap) for info on how it treats the file system and apps. My guts say to NOT trust it. Period. Much like a "normal" client side app (and remember you can store data on the desktop websites too with LocalStorage, IndexedDB,etc) you should always assume that the user can modify the values. That to me isn't a deal breaker. Being able to store stuff locally is incredibly important, but you just have to remember that it can't be trusted in terms of secured operations.
  • Commented on 02-19-2014 at 9:16 AM
    So omid - it should just work. I mean the docs that show how to list a directory, that still works fine. These changes are more involved about where you start off with when opening the file system.
  • Vinay #
    Commented on 02-20-2014 at 1:16 AM
    I am using the filetransfer plugin to download images from the server to the local file system. I get a path like 'cdvfile://localhost/persistent/...' at the end which i store for future reference. I use these cached paths to refer these images in my html using the image tag

    <img src="cdvfile://localhost/persistent/...'"/>

    This works fine when the first time but when i restart the app or navigate to some other page which iss using the same image the image doesn't load. I am seeing this behavior on simulator and on a physical device. Could you please try this out and let me know if there is some thing wrong with the way i am using the path.
    Also i use a nexus 5 for debugging and i am not able to locate the files on my device.
  • omid jafari #
    Commented on 02-20-2014 at 1:43 AM
    yeah, it works ,thanks raymond:)
  • Roman #
    Commented on 02-20-2014 at 4:20 AM
    For all who are having trouble with reading files from another direcotry (not root). This example lists all pictures within your DCIM/Camera folder:

    document.addEventListener("deviceready", onDeviceReady, false);

    function onDeviceReady() {
    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, onFSSuccess, FileError);

    //Be careful! The onFSSuccess needs the parameter fileSystem!
    //The directory path is without the prefix of the root directory!
    function onFSSuccess(fileSystem) { fileSystem.root.getDirectory("DCIM/Camera/", {create: false, exclusive: false}, doDirectoryListing, FileError);

    //dirEntry needs to be a parameter of the function!
    function doDirectoryListing(dirEntry) {
    var directoryReader = dirEntry.createReader();
    directoryReader.readEntries(gotFiles, FileError);

    function gotFiles(entries)
    for(var i=0,len=entries.length; i<len; i++)
    //Name of the picture within "DCIM/Camera"

    //This function won´t get executed if you forgot the parameter(s) of the functions
    function FileError(e)

    Thanks to RaymondCamden and SimonMacDonald!
  • George #
    Commented on 02-24-2014 at 5:31 AM
    I store gpx files locally for openlayers to display. The file paths starting with '/' and cdvfile://localhost/, that are returned by fullPath and toURL, will not work. Only a path starting with file:/// will work. Is this possible in cordova 3?
  • Commented on 02-24-2014 at 5:34 AM
    Have you tried setting the img src to a cdvfile url?
  • George #
    Commented on 02-24-2014 at 5:46 AM
    I'm not trying to display an image, I'm tring to draw a gpx track which is an xml file, for example: (see line 'url: "around_lake.gpx",'. The cdvfile url URL does not work.
  • Commented on 02-24-2014 at 6:12 AM
    Hmm. If we ignore GPX for a bit - if you do a regular XHR to the cdv url, do you get a response?
  • George #
    Commented on 02-24-2014 at 6:59 AM
    No I get an error doing a XHR to the cdv url.
  • Commented on 02-24-2014 at 7:03 AM
    Hmm, I don't know. I apologize - these new changes are confusing to me as well. What I would recommend is - post to the Google group for PhoneGap and ask about this, specifically - why you can't access the file via XHR. It seems like you should be able to. When you get a response, can you let us know?
  • Priya #
    Commented on 02-27-2014 at 12:15 AM
    Hi Raymond,
    Your blogs are very much helpful in getting a better understanding of the concepts. Thanks to you, many of my project issues were resolved even without posting in any group.

    Reg filesystem, am facing the same issue as Vinay:
    I am using the filetransfer plugin to download images from the server to the local file system. I get a path like 'cdvfile://localhost/persistent/...' at the end which i store for future reference. I use these cached paths to refer these images in my html using the image tag

    <img src="cdvfile://localhost/persistent/...'"/>

    This works fine when the first time but when i restart the app or navigate to some other page which iss using the same image the image doesn't load. I am seeing this behavior on simulator and on a physical device.

    Could you please help us resolve the same?
    Thank you.
  • matthew #
    Commented on 03-06-2014 at 12:32 AM
    I've recently upgraded and I'm having issues witht he file plugin. previously I could get a fullpath to an image that was in the gallery (android) using the code below. But now I can't. always returns undefined.

    any suggestions?

    window.resolveLocalFileSystemURL(imageURI, function(fileEntry) {
    fileEntry.file(function(fileObj) {

    newimageURI = fileObj.fullPath;

  • Priya #
    Commented on 03-06-2014 at 12:44 AM
    fileObj.toURL() to be used instead of fileObj.fullPath

    Please refer:
  • matthew #
    Commented on 03-06-2014 at 5:42 PM
    Tried that fileObj.toURL() but only get this error...

    03-07 10:08:08.123: I/Web Console(2170): processMessage failed: Stack: TypeError: Object [object Object] has no method 'toURL'

    The image in question is located in the content://media/external .... but earlier in the week when I ran the above code it returned a full image address. now nothing. I'm trying to get the address so I can use fileupload to send to a server. works fine for images captured using the camera but not from stored images.

  • Priya #
    Commented on 03-07-2014 at 8:55 AM
    @mathew please try fileObj.localURL
  • matthew #
    Commented on 03-10-2014 at 7:34 PM
    @Priya I tried fileObj.localURL and it does return a slightly different url but still not the true file path. content://media/external/images/media/86 is the imageURI then the localURL returns the same. if I select a resized version it only gives me a link to the resize.jpg with a time stamp. where the fullPath used to return a true path to the original file (if I selected a none resized image). Is there an easy way to save the resized timestamp version locally which I rename and then get access to that?
  • Tolu #
    Commented on 04-03-2014 at 4:36 AM
    Thank you for pointing out the update. Please do you have a blog post or a demo app set up to demonstrate filesysytem access in a phonegap app? What I'm particular about is how would one go about calling up the device file system and have a user select a file and probably upload to a remote server.
    The selection process is my major concern as the docs for accessing the filesystem are centered around getting a 'known' file and not leaving the user to browse and select 'any' file residing somewhere on their device. Any ideas?
  • Commented on 04-03-2014 at 5:31 AM
    I do have an earlier blog entry on the file system where I demonstrate getting a listing, which is what you would need to do. It doesn't let them browse/select, but thats the only other piece you need. Ie, add links and if they click a directory, do a listing on that then. I'll see if I can blog something more formal, but it may be a while.
  • Tolu #
    Commented on 04-03-2014 at 6:27 AM
    Thank you Raymond, while I wait for that new post, please give me the url to the old post you referred to.
  • Commented on 04-03-2014 at 7:25 AM
    Hmpth, now I can't find it. I'd suggest just browsing my phonegap blog entries via my search.
  • OOPDeveloper89 #
    Commented on 04-04-2014 at 7:05 AM
    Hello Raymond,

    thanks for this article. I have an issue by accesing the filesystem.
    I download cordova-3.4 and copied the cordova.js for android system.
    Before 3.4 I was using 2.9.1.

    The problem is LocalFileSystem is undefined. In 2.9.1 it was defined. I looked
    into the source of cordova.js and could not find LocalFileSystem. In cordova.js
    of version 2.9.1 I could find it.

    Are there other files I have to include in my index.html?
  • Commented on 04-04-2014 at 7:08 AM
    Did you add the FIleSystem plugin? Remember everything in Cordova 3.X runs via plugins you must install first.
  • OOPDeveloper89 #
    Commented on 04-04-2014 at 7:28 AM
    Yes, due the releasenotes I have version 1.0.1 (Feb 28, 2014)
  • Commented on 04-04-2014 at 7:29 AM
    I'd double check then. The error you report is pretty much exactly the one you get when trying to use a feature w/o the plugin installed.
  • OOPDeveloper89 #
    Commented on 04-04-2014 at 8:00 AM
    Hmm, I use Zend Studio 10.6 to install my phonegap plugins. The ide creates a config.xml where you can add and remove Plugins you want.
    Can I check somehow which version of plugin I have installed?
  • OOPDeveloper89 #
    Commented on 04-04-2014 at 8:07 AM
    I checked in plugin.xml.. This is the repository where the file plugin will be fetched:
    The console in Eclipse/Zend Studio says:
    Fetching plugin from location "org.apache.cordova.file"...

    And I see the plugins in the plugins/ directory of the project.
  • OOPDeveloper89 #
    Commented on 04-04-2014 at 8:18 AM
    Is it possible I just have to add other *.js files then cordova.js...
    I get it in this directory of the download file...
  • Commented on 04-04-2014 at 9:00 AM
    I would recommend not using Zend Studio to install plugins. It may not be working right. I don't know that for a fact of course, but I'd suggest using the documented way for now.
  • OOPDeveloper89 #
    Commented on 04-04-2014 at 9:15 AM
    Hmm okay, I will try it with the documented way. I let you know if it worked. Thank you very much :-)
  • oopdeveloper89 #
    Commented on 04-08-2014 at 12:32 AM
    Hello Raymond. Is it correct that value of fileSystem.root.fullPath can be just: "/"??
    Or should I get something like "file///..."
    I am using android 4.3 and phonegap 2.9...
    Maybe zend studio really did not install the plugin correctly.
    Thank you for answer :-)
  • Commented on 04-08-2014 at 10:30 AM
    Please see the upgrade notes about the FileSystem API. This in particular may be applying to you:

    "With v1.0.0, the fullPath attribute is the path to the file, relative to the root of the HTML filesystem"
  • OOPDeveloper89 #
    Commented on 04-09-2014 at 7:24 AM
    Hello again Raymond,

    sorry to ask you again. I would be happy if you can answer this:
    I need the directory entry of the "download" folder of android.
    Therefore i wrote:
       window.resolveLocalFileSystemURL('cdvfile://external/persistent/storage/emulated/0/Download', function(a) {
       }, InfopoolFileDownloadRepository.errorOccured);


    Thank you
  • Commented on 04-09-2014 at 7:59 AM
    And? You didn't say what went wrong - if anything.
  • OOPDeveloper89 #
    Commented on 04-09-2014 at 8:05 AM
    Hehe you are right..
    Well, first I tried with: 'file:///...' but I always got error code 5.
       window.resolveLocalFileSystemURL('file:///storage/emulated/0/Download', function(a) {
       }, MyObj.errorOccured);


       window.resolveLocalFileSystemURL('cdvfile:///storage/emulated/0/Download', function(a) {
       }, MyObj.errorOccured);

    wont work.

    Using cordova 3.4 and Android 4.3.

    Any idea why?

    Thank you.
  • Commented on 04-09-2014 at 8:30 AM
    From what I can see, 5 implies an encoding error, but I'm not sure how that applies here. I also did some Googling, and from what I can see, Android devs are not supposed to assume a particular folder, but rather call an API to get the folder. I think if you wanted to do this with Cordova, you would need to build a plugin that just exposed this API so you could call it from JS. In theory not too difficult to do - but you would need to write some Java.
  • mpsyp #
    Commented on 04-10-2014 at 12:44 AM
    Hello all.

    Was happy to stumble upon this thread, as I'm having some difficulty with the filesystem on a cordova project I'm working on. Having difficulty trying to access the actual file produced by the media capture plugin, despite having the full path of the file.

    Details are in a Stack Overflow post that has gone unanswered for the past few days:

    Any ideas? Any help would be greatly appreciated.

  • Commented on 04-10-2014 at 6:27 AM
    Posted a comment.
  • murali #
    Commented on 04-15-2014 at 10:26 AM
    Hello Sir
    In the new file system, we are facing one major issue.
    The css styles are not applied to any html files that are residing in the library\caches folder
    though it is not a linked style sheet. Even the inline styles are not getting applied.

    please let me know any workaround.
  • Commented on 04-15-2014 at 11:22 AM
    Hmm. I'd suggest checking w/ Remote Debugging to see if you can get a detailed error report. Best I can suggest then is to post it to the Google Group.
  • red #
    Commented on 04-17-2014 at 5:43 AM
    Ihave the same issue as matthew.
    did anybody find a solution?

    thank you
  • Commented on 04-23-2014 at 11:21 AM
    Hello Raymond,

    I am new to Phonegap and is searching for information on the file API I found your blog and thought maybe you can help me with the File API. The app captures the path a user is following using geolocation's watch mode. The path points are stored into a variable with a predefined file format known as GPX (an XML type of file for GPS data).

    I need to create the actual GPX file and allow the user to send it by email. To do so I am using the File and the Email Composer with attachments APIs and I cannot yet figure out how to connect both.

    The path points data is stored in a javascript variable named "gpxcontents". Using the file API, I am creating and storing the file to be emailed (track.gpx) as follows:

    function createGPX(fs) {
    fs.root.getFile('track.gpx', {create: true}, function(fileEntry) {
    // Create a FileWriter object for our FileEntry (track.gpx).
    fileEntry.createWriter(function(fileWriter) {
    fileWriter.onwriteend = function(e) {
    console.log('Write completed.');
    fileWriter.onerror = function(e) {
    console.log('Write failed: ' + e.toString());
    // Create a new Blob and write it to log.txt.
    var blob = new Blob([gpxcontents], {type: 'text/plain'});
    }, errorHandler);
    }, errorHandler);
    window.requestFileSystem(window.LocalFileSystem.PERSISTENT, 5*1024*1024, createGPX, errorHandler);

    Now, using Email Composer, I am building this function:

    function emailTrack(){
    window.plugins.emailComposer.showEmailComposerWithCallback(callbackEmail,'Track File','Track File sent from
    Mobile App',[] //toRecipients
    ,[] //ccRecipients
    ,[] //bccRecipients
    ,false //isHtml
    ,[] //attachments
    ,[] //attachmentsData

    and have the following questions:

    1. What shall be used as a "callbackEmail" function? is it mandatory or optional?

    2. How can I capture the path to the "track.gpx" file and add it to the attachment section of the email composer?

    3. What is the difference among "attachments" and "attachmentsData"? Shall both be used and if so how?

    I am using Phonegap Build with version 3.3 to compile the app.

    Thanks forany help you may provide.
  • Commented on 04-23-2014 at 4:00 PM
    '1. What shall be used as a "callbackEmail" function? is it mandatory or optional?'
    I don't know this plugin. If their docs do not make this clear, you should file a bug report with them so they can make it clear.

    '2. How can I capture the path to the "track.gpx" file and add it to the attachment section of the email composer? '
    The fileEntry object you used earlier should be copied to a global scope, like window.myFile = fileEntry. The full path is part of the FileEntry object - I believe just something.fullPath.

    '3. What is the difference among "attachments" and "attachmentsData"? Shall both be used and if so how?'
    See #1. ;)
  • Vignesh #
    Commented on 04-28-2014 at 5:13 PM

    Based on the above article, Chrome is going to stop working on the FileSystem APIs. How is this going to affect the Cordova FileSystem plugin?

    Thanks in advance.
  • Commented on 04-29-2014 at 10:56 AM
    I don't know to be honest - but I do know you can subscribe to the Cordova dev list where they discuss stuff exactly like this.
  • srk #
    Commented on 05-09-2014 at 6:16 AM
    I'm also having trouble reading file. I used api to take or get photo from library and i manage to save it to file system using destinationType: Camera.DestinationType.1 The location of photo something like this;
    I've also managed to send photo using;
    var ft = new FileTransfer();
    ft.upload(file_uri, encodeURI(url), photo_upload_success, photo_upload_fail, options);
    But somehow couldn't manage to read image to show in html.
    I used different thinks like;
    - remove first part of uri;
    imageURI = imageURI.substr(8);
    - don't remove
    - etc.

    Lastly i tried this function but still same;

    function get_image(imageURI){

    var reader = new FileReader();

    reader.onloadend = function(evt) {

    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail);

    function gotFS(fileSystem) {
    //fileSystem.root.getFile('tmp.tmp', {create: false, exclusive: false}, gotFileEntry, fail);
    fileSystem.root.getFile(imageURI, null, gotFileEntry, fail);

    function gotFileEntry(fileEntry) {
    function fail(error) {


    Does anyone has a working example to read image from file system on IOS?
  • Commented on 05-09-2014 at 7:21 AM
    In the future, please do not post large code blocks here.

    So - to be clear, you just want to show an image that you selected w/ getPicture?
  • srk #
    Commented on 05-09-2014 at 8:10 AM
    Sorry about it, you are right, if you want you can delete it i'll sent pastebin link.

    Correct, i just would like to show an image from fileurl. I don't use DATA_URL as destinationType to avoid memory problem.
  • Commented on 05-09-2014 at 9:38 AM
    I did a quick test and for me it worked ok. I created a virgin Cordova project and removed some of the DOM. I added an image tag with id of IMG. Here is the JS I used - it was written quickly so it isn't pretty. But it does work. I can select from the gallery and when I get the URI, I can set it to the DOM.
  • Glen #
    Commented on 05-10-2014 at 9:53 AM
    Thanks Raymond for all your great articles.
    @Alberto - I saw an email composer that said to put 'null' as the callback. The callback feature was added in order to be compatible with something.
    window.plugins.emailComposer.showEmailComposerWithCallback(null,'Track File','Track File sent from ...
    Can someone help me with attaching a file to an email? I have a web sql form that is exported to a text file through javascript. Logcat in Android Eclipse says the file is saved to cdvfile://localhost/temporary/profile.txt: 6124. The file is in the cache folder of my app.
    I am using the katzer email compoer. He says to attach a file like this -{
    attachments: [
    'file://storage/sdcard/icon.jpg', //=> Android
    He says it can be used for text files to, but I can't get it to work. I even changed the file name to jpg.
  • srk #
    Commented on 05-12-2014 at 4:19 AM
    Thanks Raymond, i was trying to read file, but i saw that it more easy to use uri directly.
    Thank you so much for help and also for article.
  • sergio #
    Commented on 05-14-2014 at 10:52 AM
    Hi Raymond, thanks for your post. I cannot write a file on the private memory of an android application. Please could you try and help me? This is my stackoverflow post:

    I am new to phonegap but I think it would be used much more if there was more support of stackoverflow ...
    Thank you
  • Commented on 05-18-2014 at 2:49 PM
    I was at a conference - it looks like you got the support you needed.
  • sergio #
    Commented on 05-19-2014 at 4:22 AM
    yes I managed it, Thanks for your job and help anyway.
  • Commented on 05-20-2014 at 11:42 AM

    Sorry for my late reply, I just saw your post. Thanks for your comment. I had figured out the role of that function and it seems to be needed by iOS somehow.

    Anyway, we have figured out how to work with the new File API and native file paths. There is a new method "toNativeURL() " that allows to convert a fileEntry path to a native file path. Please check this thread in the Phonegap Build Community Forum for more details:

    I hope it helps.
  • murali #
    Commented on 07-16-2014 at 5:40 AM
    Hello Sir,
    Is there any way, where we could use the cordova api functions inside a local page that opens up in inappbrowser.

    say sample.html which is opened in inappbrowser. This html uses jquery and cordova.js files.
    'document ready' is triggered but device ready is not triggered and iam unable to use any of the cordova functionalities. Is there any work around for this. as i need access to cordova.js functionality and also the local database files to fetch and display the details.

  • Commented on 07-16-2014 at 10:04 AM
    In theory, yes, but it will not be easy. Only the parent doc can do "Cordova stuff", and you can't "talk" to the parent from the child. The closest you can do is poll for messages from the parent. See this:'s-inappbrowser
  • bharat #
    Commented on 07-31-2014 at 1:57 PM
    I used the barcode scanner plugin that i found in repository and now i am working on that after i scan like said 10 items i want to save it text file and send that text file through email in iphone/ipad.

    Any help would be greatly appreciated.

    Thank you
  • Commented on 07-31-2014 at 2:07 PM
    @bharat: Your question is a bit broad. Can you ask one specific question to narrow it down?
  • Commented on 08-21-2014 at 4:49 AM
    I have a page hosted online accessed that page in my phonegap application but now i want to come back to my local files in


    but it gives me error:

    08-21 14:08:00.324: E/Web Console(8304): Not allowed to load local resource: file:///android_asset/www/profile.html at null:0

    How do I fix this issue.
  • Commented on 08-21-2014 at 6:57 AM
    I don't quite understand your question. How are you trying to load that file?
  • Commented on 08-21-2014 at 8:22 AM
    Trying to access local page in href
    <a href="file:///android_asset/www/hyperextend.html';">Ext</a>
  • Commented on 08-21-2014 at 8:24 AM

    one page is added on my local folder and want to open that page using <a href="file:///android_asset/www/hyperextend.html';">Ext</a>
  • Commented on 08-21-2014 at 9:17 AM
    If it is local, why are you using file:///? Just link to hyerextend.html.
  • Commented on 08-21-2014 at 9:35 AM
    But my index file in online and i need only one file due to some reasons online and after that file need to come back to my local files
  • Commented on 08-21-2014 at 10:48 AM
    Then I wouldn't do that I guess. I'd fetch the remote content from a local index.html.
  • Commented on 10-17-2014 at 4:01 AM
    There is a method that can be used to return to the 1st page... it's not ideal but it might be of use.

    window.history.go( -( history.length - 1 ) );
  • sarika #
    Commented on 11-15-2014 at 4:19 AM
    I have this question on , i want to download file from my app? whats wrong there am not getting....Help me!