使用 OS.File 在文件中持久存储 JSON

Persistence storage JSON in a file using OS.File

如何使用 OS.File 以 OS 独立的方式在文件中的 JSON 的 firefox addon sdk 中进行持久性存储? 就像我将文件保存在 windows 中的 D:\file 中一样,它在 linux 中甚至在没有驱动器的 windows 中都不起作用 :D.

我该怎么做?

要将 realObject 作为 JSON 存储在文件 MyFileName.json 中,即当前配置文件目录中 extension-data 目录中的 created/overwritten,您可以做类似的事情:

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);
        }
    });
}