QNimate

  • CoursesVideos
  • WP PremiumPlugins
  • DemosLab
  • Home
  • QIdea
  • QTrack
Home Carbon Ads Working with File System using Intel XDK

Working with File System using Intel XDK

filesystem

This post is a part 27 of Intel XDK Complete Tutorial post series.

In this tutorial I will introduce you to APIs using which you can work with the device filesystem. Filesystem APIs will help you create audio, images, cloud etc applications.

Cordova File API

There is actually no Intel XDK plugin/API to work with file system. But there is a cordova plugin called as File API plugin using which we can access the filesystem.

Before we continue exploring this API you need to included this plugin in your project. You can do this by select the File checkbox in you Intel XDK project dashboard.

Screen Shot 2014-11-21 at 7.44.56 pm

Application Data Storage Directory

When an application is installed, mobile OS assigns an unique directory to the application where the app can store files. This directory is called application storage directory for that app.

Inside the application storage directory there are many other directories such as directory for storing code files, for storing permanent data, for storing cache data, for storing temporary data, data to be cloud synced etc. The name and path of these sub directories differ depending on the operating system.

Some operating systems also allow the app to store data outside the application storage directory i.e., SD card, shared directory etc.

DirectoryEntry and FileEntry

A DirectoryEntry object is a pointer to a directory. Similarly FileEntry is a pointer to a file.

A DirectoryEntry object can be used to create files/subdirectories. A DirectoryEntry object cannot access files/directories which is inside of an another directory i.e., it has access to its children but not children of children.

A FileEntry object can be used to write or read a file. We can get a FileEntry object for a file using its first parent’s DirectoryEntry object.

A DirectoryEntry object for a directory can retrieved using its first parent’s(i.e., nearest parent in the tree) DirectoryEntry object. DirectoryEntry for permanent or temporary directories in the application storage directory can be retrieved using FileSystem object.

        document.addEventListener("deviceready", onDeviceReady, false);
       
        function onDeviceReady()
        {
            //PERSISTENT indicates that any change we make to the file system now will be permanent.
            requestFileSystem(LocalFileSystem.PERSISTENT, 0, onSuccess, onError);
        }

        //fileSystem object points to the complete mobile file system.
        function onSuccess(fileSystem)
        {
            //fileSystem.root points to the application storage directory
            var directoryEntry = fileSystem.root;  
        }
       
       function onError(evt)
        {
            console.log("Error occurred during request to file system pointer. Error code is: " + evt.code);
        }

LocalFileSystem.PERSISTENT indicates that any change we make to the application storage directory using application storage’s DirectoryEntry and its sub DirectoryEntry’s will be permanent. If we pass LocalFileSystem.TEMPORARY than any change we make to the application storage directory using application storage’s DirectoryEntry and its sub DirectoryEntry’s will be temporary i.e., will be reset once application is terminated.

Actually LocalFileSystem.PERSISTENT gets directoryEntry object pointing to the directory which stores permanent data. Similarly LocalFileSystem.TEMPORARY gets directoryEntry object pointing to the directory which stores temporary data. As I said earlier there are various different directories in the application storage and outside it. Here is an guide which shows how to get directoryEntry objects for other different directories and also explains how they behave.

Path of a File or Directory

There are two kinds of path to a file/directory i.e., filesytem path and URL. They both can be used alternative to each other.

DirectoryEntry object can return both types of paths of the directory its pointing to. Similarly FileEntry can return both types of paths of the file its pointing to.

Here is an example of retrieving path of application storage directory:

        document.addEventListener("deviceready", onDeviceReady, false);
       
        function onDeviceReady()
        {
            requestFileSystem(LocalFileSystem.PERSISTENT, 0, onSuccess, onError);
        }
       
        function onSuccess(fileSystem)
        {  
            var directoryEntry = fileSystem.root;
         
            //absolute fileSystem path to the application storage directory
            console.log(directoryEntry.fullPath);
           
            //web path(or URL) to the application storage directory
            console.log(directoryEntry.toURL());
        }
       
        function onError(evt)
        {
            console.log("Error occurred during request to file system pointer. Error code is: " + evt.code);
        }

Creating a File and Writing Data to it

We can create a file using DirectoryEntry object of its first parent directory. He can use the DirectoryEntry object retrieved above to create a file inside the application storage directory.

Once we create a file we will have a FileEntry object for that file passed as callback parameter. Using it we can write data to the file.

Here is the code to create a file:

        document.addEventListener("deviceready", onDeviceReady, false);
       
        function onDeviceReady()
        {
            requestFileSystem(LocalFileSystem.PERSISTENT, 0, onSuccess, onError);
        }
       
        function onSuccess(fileSystem)
        {  
            var directoryEntry = fileSystem.root;
           
            //lets create a file named readme.txt. getFile method actually creates a file and returns a pointer(FileEntry) if it doesn't exist otherwise just returns a pointer to it. It returns the file pointer as callback parameter.
            directoryEntry.getFile("readme.txt", {create: true, exclusive: false}, function(fileEntry){
                //lets write something into the file
                fileEntry.createWriter(function(writer){
                    writer.write("This is the text inside readme file");
                }, function(error){
                    console.log("Error occurred while writing to file. Error code is: " + error.code);
                });
            }, function(error){
                console.log("Error occurred while getting a pointer to file. Error code is: " + error.code);
            });
        }
       
        function onError(evt)
        {
            console.log("Error occurred during request to file system pointer. Error code is: " + evt.code);
        }

You can write text or binary data to a file. In the above code we wrote textual data to a file. Here is a sample code on how you would write binary data to a file

function(writer) {
    var data = new ArrayBuffer(5),
    dataView = new Int8Array(data);
    for (i=0; i < 5; i++)
    {
        dataView[i] = i;
    }
    writer.write(data);
};

Read Contents of a File

Using FileEntry object we can read contents of a file. In the above code we saw how to get FileEntry object using DirectoryEntry object.

Here is the code to read content of the file we created

        document.addEventListener("deviceready", onDeviceReady, false);
       
        function onDeviceReady()
        {
            requestFileSystem(LocalFileSystem.PERSISTENT, 0, onSuccess, onError);
        }
       
        function onSuccess(fileSystem)
        {  
            var directoryEntry = fileSystem.root;
           
            directoryEntry.getFile("readme.txt", {create: true, exclusive: false}, function(fileEntry){
                //lets read the content of the file.
                fileEntry.file(function(file){
                    //FileReader object streams the content of the file from storage disk to app
                    var reader = new FileReader();
                    reader.onloadend = function (evt) {
                        //result property is string type if you read data as string. If you read data as array buffer then its assigned to a array buffer object.
                        console.log(evt.target.result);
                    };
                    //to read the content as binary use readAsArrayBuffer function.
                    reader.readAsText(file);
                }, function(error){
                    console.log("Error occurred while readline file. Error code is: " + error.code);  
                });
               
            }, function(error){
                console.log("Error occurred while getting a pointer to file. Error code is: " + error.code);
            });
   
        }
       
        function onError(evt)
        {
            console.log("Error occurred during request to file system pointer. Error code is: " + evt.code);
        }

We can read file data as text or binary. In the above code we read textual data from file. Here is a sample code on how you would read binary data from a file

function(file) {
    var reader = new FileReader();
    reader.onloadend = function (evt) {
        console.log(new Uint8Array(evt.target.result));
    };
    reader.readAsArrayBuffer(file);
};

Path of a File

We already saw a code example of getting path of a directory. Let’s see how to get the path of a file using FileEntry object.

        document.addEventListener("deviceready", onDeviceReady, false);
       
        function onDeviceReady()
        {
            requestFileSystem(LocalFileSystem.PERSISTENT, 0, onSuccess, onError);
        }
       
        function onSuccess(fileSystem)
        {  
            var directoryEntry = fileSystem.root;
           
            directoryEntry.getFile("readme.txt", {create: true, exclusive: false}, function(fileEntry){
                //absolute fileSystem path to the readme.txt file
                console.log(fileEntry.fullPath);

                //web path(or URL) to the readme.txt file
                console.log(fileEntry.toURL());      
           
            }, function(error){
                console.log("Error occurred while getting a pointer to file. Error code is: " + error.code);
            });
        }
       
        function onError(evt)
        {
            console.log("Error occurred during request to file system pointer. Error code is: " + evt.code);
        }

Creating a Directory

We can create a directory using DirectoryEntry object. It can only create as a sub directory but not a directory as sub-sub-directory or at the same level as itself.

Here is the code to create a sub directory inside application storage directory

        document.addEventListener("deviceready", onDeviceReady, false);
       
        function onDeviceReady()
        {
            requestFileSystem(LocalFileSystem.PERSISTENT, 0, onSuccess, onError);
        }
       
        function onSuccess(fileSystem)
        {  
            var directoryEntry = fileSystem.root;
           
            //create a directory using getDirectory. If already exists it returns a pointer only.
            directoryEntry.getDirectory("new_directory", {create: true, exclusive: false}, function(directoryEntry_1){
                //for any operation inside this directory use directoryEntry_1 object.
            }, function(error){
                console.log("Error occurred while getting pointer to new directory. Error code is: " + error.code);
            });
        }
       
        function onError(evt)
        {
            console.log("Error occurred during request to file system pointer. Error code is: " + evt.code);
        }

Here DirectoryEntry to our newly created directory is passed as callback. This is how you can point to different directories using their parent DirectoryEntry to make changes in them.

Find Contents in a Directory

You can find the contents in a directory using its DirectoryEntry object.

Here is the code to find contents inside the application storage directory

        document.addEventListener("deviceready", onDeviceReady, false);
       
        function onDeviceReady()
        {
            requestFileSystem(LocalFileSystem.PERSISTENT, 0, onSuccess, onError);
        }
       
        function onSuccess(fileSystem)
        {  
            var directoryEntry = fileSystem.root;
           
            //object to read the contents of the directory
            var directoryReader = directoryEntry.createReader();
           
            //now read the contents using the readEntries function.
            directoryReader.readEntries(function(entries){
                var i;
                for (i=0; i<entries.length; i++)
                {
                    console.log(entries[i].name);
                }
            },function(error){
                console.log("Failed to list directory contents. Error code is: " + error.code);
            });
        }
       
        function onError(evt)
        {
            console.log("Error occurred during request to file system pointer. Error code is: " + evt.code);
        }

Final Code

Here I have mixed all code into one snippet to show a workflow.

        document.addEventListener("deviceready", onDeviceReady, false);
       
        function onDeviceReady()
        {
            //PERSISTENT indicates that any change we make to the file system now will be permanent.
            requestFileSystem(LocalFileSystem.PERSISTENT, 0, onSuccess, onError);
        }
       
        //fileSystem object points to the hard disk.
        function onSuccess(fileSystem)
        {  
            //fileSystem.root points to the application storage directory
            var directoryEntry = fileSystem.root;
         
            //absolute fileSystem path to the application storage directory
            console.log(directoryEntry.fullPath);
           
            //web path(or URL) to the application storage directory
            console.log(directoryEntry.toURL());
           
            //lets create a file named readme.txt. getFile method actually creates a file and returns a pointer(FileEntry) if it doesn't exist otherwise just returns a pointer to it. It returns the file pointer as callback parameter.
            directoryEntry.getFile("readme.txt", {create: true, exclusive: false}, function(fileEntry){
                //lets write something into the file
                fileEntry.createWriter(function(writer){
                    writer.write("This is the text inside readme file");
                }, function(error){
                    console.log("Error occurred while writing to file. Error code is: " + error.code);
                });
               
                //lets read the content of the file.
                fileEntry.file(function(file){
                    var reader = new FileReader();
                    reader.onloadend = function (evt) {
                        //result property is string type if you read data as string. If you read data as array buffer then its assigned to a array buffer object.
                        console.log(evt.target.result);
                    };
                    //to read the content as binary use readAsArrayBuffer function.
                    reader.readAsText(file);
                }, function(error){
                    console.log("Error occurred while readline file. Error code is: " + error.code);  
                });
               
            }, function(error){
                console.log("Error occurred while getting a pointer to file. Error code is: " + error.code);
            });
           
            //create a directory using getDirectory. If already exists it returns a pointer only.
            directoryEntry.getDirectory("new_directory", {create: true, exclusive: false}, function(directoryEntry_1){
                //for any operation inside this directory use directoryEntry_1 object.
            }, function(error){
                console.log("Error occurred while getting pointer to new directory. Error code is: " + error.code);
            });
           
            //object to read the contents of the directory
            var directoryReader = directoryEntry.createReader();
           
            //now read the contents using the readEntries function.
            directoryReader.readEntries(function(entries){
                var i;
                for (i=0; i<entries.length; i++)
                {
                    console.log(entries[i].name);
                }
            },function(error){
                console.log("Failed to list directory contents. Error code is: " + error.code);
            });
        }
       
        function onError(evt)
        {
            console.log("Error occurred during request to file system pointer. Error code is: " + evt.code);
        }

Path of WWW Directory

WWW directory is also stored inside application storage directory. But the name of this directory after build is different. Therefore its difficult to find path to it. Instead you can use the below code to find the path of the www directory.

//returns absolute filesystem path to the www directory.
function getAbsolutePath() {
    "use strict" ;
    var path = window.location.pathname ;
    path = path.substring( 0, path.lastIndexOf('/') ) ;
    return path ;
}

//returns URL pointing to the www directory.
function getWebRoot() {
    "use strict" ;
    var path = window.location.href ;
    path = path.substring( 0, path.lastIndexOf('/') ) ;
    return path ;
}

Now you can create a file anywhere in the application storage and then move it to the www directory using FileEntry’s moveTo function.

Final Thoughts

You can refer to Cordova File API documentation to learn in depth about all methods and properties of the objects I mentioned. I tried to simplify everything so that you can get started with the API.

Nov 21, 2014Narayan Prusty
Create an Frontend Editor with Code Highlighting and ExecutionUploading Files and Showing Progress using Intel XDK
Comments: 15
  1. Subin
    6 years ago

    Its not work for me, function run complete .but not creating the folder and file . Where can i found the project file to download .

    Hope you look forward for me.

    Thanks in Advance

    ReplyCancel
  2. Nowdeen
    6 years ago

    Hi Narayan, thanks for your time spent to create this tutorial.
    Please, can you explain us if is possible (I think it is) create and manage files using deep hierarquies like: cordova.file.dataDirectory/client/user/profile/picture/image.png? I am googling for days and nothing that I saw indicates it is possible or how to achieve it.

    ReplyCancel
    • Trendy Status
      6 years ago

      Hello there I am so delighted I found your weblog, I really found you by mistake, while I was searching on Google for something else, Anyhow I am here now and would just like to say cheers for a remarkable post and a all round exciting blog (I also love the theme/design), I don’t have time to browse it all at the moment but I have book-marked it and also included your RSS feeds, so when I have time I will be back to read a lot more, Please do keep up the superb work.

      ReplyCancel
  3. Daniele
    7 years ago

    Hi @narayanprusty in first thanks for share your code.. i try to use filesystem in intel xdk but i recevied in consol log error ;
    cdvfile://localhost/file__0:Persistent/ index_user_scripts.js:85
    Error occurred while getting a pointer to file. Error code is: 1 index_user_scripts.js:110
    Error occurred while getting pointer to new directory. Error code is: 1 index_user_scripts.js:117
    Failed to list directory contents. Error code is: 1

    where i mistake ? Help

    ReplyCancel
  4. Zalizan
    7 years ago

    Hi, i’m having problem with upload file in intel xdk. i’m using jquery mobile and input type=file. the reader seem can’t read the file. Need help because when i your code, reader onload working fine. Below are the code:

    function doOpen() {
    var fileUploadControl = $("#uploadFile")[0];
    var filesToUpload = fileUploadControl.files[0];
    console.log("files: "+filesToUpload);
    console.log("value: "+$("#uploadFile").val());
    var fileType = "image/"+$("#uploadFile").val().split('.').pop();
    console.log("type: "+fileType);

    readFile(filesToUpload, fileType);}
    function readFile(file, fileType) {
    var reader = new FileReader();
    reader.onloadend = function () {
    console.log(reader.result+","+fileType);
    processFile(reader.result, fileType);
    //var showout = document.getElementById('showresult');
    //showout.value = reader.result;
    }

    reader.onerror = function (error) { // **the app will throw error here**
    alert('reader error');
    }

    reader.readAsDataURL(file);}

    function processFile(dataURL, fileType) {
    var maxWidth = 800;
    var maxHeight = 800;

    var image = new Image();
    image.src = dataURL;

    image.onloadend = function () {
    var width = image.width;
    var height = image.height;
    var shouldResize = (width > maxWidth) || (height > maxHeight);

    if (!shouldResize) {
    dataURL = dataURL.substring(dataURL.indexOf(',')+1);
    console.log(dataURL);
    storeObject.ImageT = fileType;
    storeObject.cImage = dataURL;
    //addNewThread();
    //sendFile(dataURL);
    //var showout = document.getElementById('showresult');
    //showout.value = dataURL;
    return;
    }

    var newWidth;
    var newHeight;

    if (width > height) {
    newHeight = height * (maxWidth / width);
    newWidth = maxWidth;
    } else {
    newWidth = width * (maxHeight / height);
    newHeight = maxHeight;
    }

    var canvas = document.createElement('canvas');

    canvas.width = newWidth;
    canvas.height = newHeight;

    var context = canvas.getContext('2d');

    context.drawImage(this, 0, 0, newWidth, newHeight);

    dataURL = canvas.toDataURL(fileType,0.7);
    dataURL = dataURL.substring(dataURL.indexOf(',')+1);
    console.log(dataURL);
    storeObject.cImage = dataURL;
    storeObject.ImageT = fileType;
    //addNewThread();
    //sendFile(dataURL);
    //var showout = document.getElementById('showresult');
    //showout.value = dataURL;
    };

    image.onerror = function () {
    alert('image error');
    };
    }

    ReplyCancel
  5. aqsa
    7 years ago

    Hi …. how to store application data on facebook.. like i want to store a form i’e name year amount etc…
    ??

    ReplyCancel
  6. mohammed
    7 years ago

    please help : erorr below :

    cdvfile://localhost/file__0:Persistent/ index_user_scripts.js:42
    Error occurred while getting a pointer to file. Error code is: 1 index_user_scripts.js:67
    Error occurred while getting pointer to new directory. Error code is: 1 index_user_scripts.js:74
    Failed to list directory contents. Error code is: 1 index_user_scripts.js:88
    Failed to load resource: the server responded with a status of 404 (Not Found) http://127.0.0.1:58889/http-services/emulator-webserver/ripple/userapp/x/C/…-4b76917e2653/platforms/android/assets/www/jqm/jquery.mobile-1.4.2.min.map

    ReplyCancel
  7. Ovidio
    7 years ago

    Hi,
    I’m new to phone app development, and there are things that I don’t know how to achieve.
    I want to read and play the ringtones stored in the Ringtones directory of a mobile, this directory is located in a SDcard, how can I do this?. Using the fle manager of the phone I can see the files stored, so they exist.
    Thank you in advance, any light you can shed will be highly appreciated
    Have a nice day

    ReplyCancel
  8. Kunal
    7 years ago

    I am doing a HTTP GET, where I receive an image (PNG).
    How do I write it to a file?

    ReplyCancel
  9. rahulkkikani
    8 years ago

    I have same problem as other people having. I couldn’t read/write in www directory after building application. I’m getting error code 1000. There should be some problem with system file pointer. I’m using Intel XDK. It’s working with Intel Application Preview. But not working when we building app separately. by the way This article is very helpful for me.

    ReplyCancel
  10. Kobus Viljoen
    8 years ago

    Great tutorial, exactly what I was looking for. Is there a way to create the DirectoryEntry object in the www directory so that the app can work (create files etc…) directly inside the www directory. Or do I have to create all the files in app storage and then move to the www directory?

    ReplyCancel
  11. Esha Upadhyay
    8 years ago

    Hi, Thanks for the tutorial.This was something I was looking for.I am using above code in my development work.But is struck with two questions

    I have file readme.txt inside my www directory. I am using above code to read it.But it is not working I am getting file not found ( file status code 1)in getfile call. Could you please help me with this

    ReplyCancel
  12. Zack Snyders
    8 years ago

    Great stuff. Can you provide me with a few guidelines of how to apply this into the Intel XDK App Designer. i.e. Where to put the scripts, in the index_user_scripts.js section, etc.

    ReplyCancel
    • Narayan Prusty
      8 years ago

      You can put the above scripts anywhere in any js file. Make sure you run them after cordova ready event.

      ReplyCancel
  13. Hedi Herdiana
    8 years ago

    Great tutorial!! but where the sample full source code in index.html, I did not find it.

    ReplyCancel

Leave a Reply to Zack Snyders Cancel reply

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax

Narayan Prusty

I am a software engineer specialising in Blockchain, DevOps and Go/JavaScript. This is my personal blog where I write about things that I learn and feel interesting to share.

Image8 years ago 17 Comments Cordova
Share this
0
GooglePlus
0
Facebook
0
Twitter
0
Linkedin
  • Cordova File API
  • Application Data Storage Directory
  • DirectoryEntry and FileEntry
  • Path of a File or Directory
  • Creating a File and Writing Data to it
  • Read Contents of a File
  • Path of a File
  • Creating a Directory
  • Find Contents in a Directory
  • Final Code
  • Path of WWW Directory
  • Final Thoughts
Related Articles
  • Find Recorded Audio File Location in Cordova
  • Push Notification in Intel XDK using Push Plugin
  • Storing Data Locally in a Intel XDK App
  • Twitter Login in Intel XDK APP using ngCordovaOauth
  • Create a Mobile app using Intel XDK and Ionic Framework
Our Sponsor
My Books

2014 - 2015 © QNimate
All tutorials MIT license