Search code examples
javascriptfirefoxfirefox-addonfirefox-addon-sdk

Persistence storage JSON in a file using OS.File


How to do a Persistence storage in firefox addon sdk of JSON in a file using OS.File in OS independent way? Like if I save the file in D:\file in windows, it wont work in linux or even on windows without drive :D.

How do I go about doing this?


Solution

  • To store realObject as JSON in the file MyFileName.json which is created/overwritten in the extension-data directory within the directory for the current profile, you could do something like:

    Components.utils.import("resource://gre/modules/FileUtils.jsm");
    Components.utils.import("resource://gre/modules/NetUtil.jsm");
    Components.utils.import("resource://gre/modules/Services.jsm");
    
    let asJSON = JSON.stringify(realObject,null);
    let file2 = openFileInPrefsExtensionData("MyFileName.json");
    overwriteTextFileFromString (file2, asJSON);
    
    
    /**
     * Open file in Extension's extension-data directory under the pref Directory.
     *   This is the correct place to store files for your extension under the profile's
     *   directory.
     */
    function openFileInPrefsExtensionData(filename) {
        let fileNameList = ["extension-data","MyExtensionID"];
        fileNameList.push(filename);
        //This does create all directories along the way to the file,
        //  but the file itself is not created.
        return FileUtils.getFile("ProfD", fileNameList);
    }
    
    
    /**
     * Overwrite a file from a string.
     *  Currently this just overwrites, without any callback function at the end
     *  of the write.  If the write fails, then it is reported in the console,
     *  but not otherwise handled.
     */
    function overwriteTextFileFromString(file,data) {
        overwriteTextFile(file, data, function (status) {
        });
    }
    
    /**
     * Overwrite a file with a string.
     */
    function overwriteTextFile(nsiFile, data, flags, callback) {
        //data is data you want to write to file
        //if file doesnt exist it is created
        // You can also optionally pass a flags parameter here. It defaults to
        // FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE | FileUtils.MODE_TRUNCATE;
    
        //PR_RDONLY         0x01    Open for reading only.
        //PR_WRONLY         0x02    Open for writing only.
        //PR_RDWR           0x04    Open for reading and writing.
        //PR_CREATE_FILE    0x08    If the file does not exist, the file is created. If the file exists, this flag has no effect.
        //PR_APPEND         0x10    The file pointer is set to the end of the file prior to each write.
        //PR_TRUNCATE       0x20    If the file exists, its length is truncated to 0.
        //PR_SYNC           0x40    If set, each write will wait for both the file data and file status to be physically updated.
        //PR_EXCL           0x80    With PR_CREATE_FILE, if the file does not exist, the file is created. If the file already exists, no action and NULL is returned.
    
        let args = Array.prototype.slice.call(arguments,4);
    
        if(typeof flags == "undefined") {
            //These are already the defaults.
            flags = FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE | FileUtils.MODE_TRUNCATE;
        }
        //XXX NOTE: Flags is currently not being used.  I don't recall why I disabled its use.
    
        var ostream = FileUtils.openSafeFileOutputStream(nsiFile);
        var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
        converter.charset = "UTF-8";
        var istream = converter.convertToInputStream(data);
        // The last argument (the callback) is optional.
        //asyncCopy automatically closes both the input and output streams upon completion.
        NetUtil.asyncCopy(istream, ostream, function (status) {
            if (!Components.isSuccessCode(status)) {
                // Handle error!
                Components.utils.reportError('error on write isSuccessCode = ' + status);
                return;
            }
            // Data has been written to the file.
            //send the status, and any other args to the callback function.
            args.unshift(status);
            if(typeof callback == "function" ) {
                //there is a callback function..
                callback.apply(callback, args);
            }
        });
    }