michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: this.EXPORTED_SYMBOLS = [ "FileUtils" ]; michael@0: michael@0: Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); michael@0: michael@0: const Cc = Components.classes; michael@0: const Ci = Components.interfaces; michael@0: const Cr = Components.results; michael@0: michael@0: XPCOMUtils.defineLazyServiceGetter(this, "gDirService", michael@0: "@mozilla.org/file/directory_service;1", michael@0: "nsIProperties"); michael@0: michael@0: this.FileUtils = { michael@0: MODE_RDONLY : 0x01, michael@0: MODE_WRONLY : 0x02, michael@0: MODE_RDWR : 0x04, michael@0: MODE_CREATE : 0x08, michael@0: MODE_APPEND : 0x10, michael@0: MODE_TRUNCATE : 0x20, michael@0: michael@0: PERMS_FILE : 0o644, michael@0: PERMS_DIRECTORY : 0o755, michael@0: michael@0: /** michael@0: * Gets a file at the specified hierarchy under a nsIDirectoryService key. michael@0: * @param key michael@0: * The Directory Service Key to start from michael@0: * @param pathArray michael@0: * An array of path components to locate beneath the directory michael@0: * specified by |key|. The last item in this array must be the michael@0: * leaf name of a file. michael@0: * @return nsIFile object for the file specified. The file is NOT created michael@0: * if it does not exist, however all required directories along michael@0: * the way are. michael@0: */ michael@0: getFile: function FileUtils_getFile(key, pathArray, followLinks) { michael@0: var file = this.getDir(key, pathArray.slice(0, -1), true, followLinks); michael@0: file.append(pathArray[pathArray.length - 1]); michael@0: return file; michael@0: }, michael@0: michael@0: /** michael@0: * Gets a directory at the specified hierarchy under a nsIDirectoryService michael@0: * key. michael@0: * @param key michael@0: * The Directory Service Key to start from michael@0: * @param pathArray michael@0: * An array of path components to locate beneath the directory michael@0: * specified by |key| michael@0: * @param shouldCreate michael@0: * true if the directory hierarchy specified in |pathArray| michael@0: * should be created if it does not exist, false otherwise. michael@0: * @param followLinks (optional) michael@0: * true if links should be followed, false otherwise. michael@0: * @return nsIFile object for the location specified. michael@0: */ michael@0: getDir: function FileUtils_getDir(key, pathArray, shouldCreate, followLinks) { michael@0: var dir = gDirService.get(key, Ci.nsIFile); michael@0: for (var i = 0; i < pathArray.length; ++i) { michael@0: dir.append(pathArray[i]); michael@0: } michael@0: michael@0: if (shouldCreate) { michael@0: try { michael@0: dir.create(Ci.nsIFile.DIRECTORY_TYPE, this.PERMS_DIRECTORY); michael@0: } catch (ex if ex.result == Cr.NS_ERROR_FILE_ALREADY_EXISTS) { michael@0: // Ignore the exception due to a directory that already exists. michael@0: } michael@0: } michael@0: michael@0: if (!followLinks) michael@0: dir.followLinks = false; michael@0: return dir; michael@0: }, michael@0: michael@0: /** michael@0: * Opens a file output stream for writing. michael@0: * @param file michael@0: * The file to write to. michael@0: * @param modeFlags michael@0: * (optional) File open flags. Can be undefined. michael@0: * @returns nsIFileOutputStream to write to. michael@0: * @note The stream is initialized with the DEFER_OPEN behavior flag. michael@0: * See nsIFileOutputStream. michael@0: */ michael@0: openFileOutputStream: function FileUtils_openFileOutputStream(file, modeFlags) { michael@0: var fos = Cc["@mozilla.org/network/file-output-stream;1"]. michael@0: createInstance(Ci.nsIFileOutputStream); michael@0: return this._initFileOutputStream(fos, file, modeFlags); michael@0: }, michael@0: michael@0: /** michael@0: * Opens an atomic file output stream for writing. michael@0: * @param file michael@0: * The file to write to. michael@0: * @param modeFlags michael@0: * (optional) File open flags. Can be undefined. michael@0: * @returns nsIFileOutputStream to write to. michael@0: * @note The stream is initialized with the DEFER_OPEN behavior flag. michael@0: * See nsIFileOutputStream. michael@0: * OpeanAtomicFileOutputStream is generally better than openSafeFileOutputStream michael@0: * baecause flushing is not needed in most of the issues. michael@0: */ michael@0: openAtomicFileOutputStream: function FileUtils_openAtomicFileOutputStream(file, modeFlags) { michael@0: var fos = Cc["@mozilla.org/network/atomic-file-output-stream;1"]. michael@0: createInstance(Ci.nsIFileOutputStream); michael@0: return this._initFileOutputStream(fos, file, modeFlags); michael@0: }, michael@0: michael@0: /** michael@0: * Opens a safe file output stream for writing. michael@0: * @param file michael@0: * The file to write to. michael@0: * @param modeFlags michael@0: * (optional) File open flags. Can be undefined. michael@0: * @returns nsIFileOutputStream to write to. michael@0: * @note The stream is initialized with the DEFER_OPEN behavior flag. michael@0: * See nsIFileOutputStream. michael@0: */ michael@0: openSafeFileOutputStream: function FileUtils_openSafeFileOutputStream(file, modeFlags) { michael@0: var fos = Cc["@mozilla.org/network/safe-file-output-stream;1"]. michael@0: createInstance(Ci.nsIFileOutputStream); michael@0: return this._initFileOutputStream(fos, file, modeFlags); michael@0: }, michael@0: michael@0: _initFileOutputStream: function FileUtils__initFileOutputStream(fos, file, modeFlags) { michael@0: if (modeFlags === undefined) michael@0: modeFlags = this.MODE_WRONLY | this.MODE_CREATE | this.MODE_TRUNCATE; michael@0: fos.init(file, modeFlags, this.PERMS_FILE, fos.DEFER_OPEN); michael@0: return fos; michael@0: }, michael@0: michael@0: /** michael@0: * Closes an atomic file output stream. michael@0: * @param stream michael@0: * The stream to close. michael@0: */ michael@0: closeAtomicFileOutputStream: function FileUtils_closeAtomicFileOutputStream(stream) { michael@0: if (stream instanceof Ci.nsISafeOutputStream) { michael@0: try { michael@0: stream.finish(); michael@0: return; michael@0: } michael@0: catch (e) { michael@0: } michael@0: } michael@0: stream.close(); michael@0: }, michael@0: michael@0: /** michael@0: * Closes a safe file output stream. michael@0: * @param stream michael@0: * The stream to close. michael@0: */ michael@0: closeSafeFileOutputStream: function FileUtils_closeSafeFileOutputStream(stream) { michael@0: if (stream instanceof Ci.nsISafeOutputStream) { michael@0: try { michael@0: stream.finish(); michael@0: return; michael@0: } michael@0: catch (e) { michael@0: } michael@0: } michael@0: stream.close(); michael@0: }, michael@0: michael@0: File: Components.Constructor("@mozilla.org/file/local;1", Ci.nsILocalFile, "initWithPath") michael@0: };