File IOFrom MozillaZine Knowledge Base(Difference between revisions)
Revision as of 18:27, 7 March 2005This page is part of the extension development documentation project. Ask your questions in MozillaZine Forums. Also try browsing example code. Note: development documentation is in process of being moved to Mozilla Development Center (MDC). This article describes local file input/output in chrome Javascript. You access the filesystem using Mozilla XPCOM components. The list of components used for local I/O is available at XulPlanet.com.
Available librariesThere are a few Javascript wrappers for I/O XPCOM components. See JSLib and jsio.js (original by MonkeeSage). The jsio module is much smaller and very easy to use (simple examples are included in the module). Creating a file object ("opening" files)var file = Components.classes["@mozilla.org/file/local;1"]. createInstance(Components.interfaces.nsILocalFile); file.initWithPath("/home"); Note, that the path passed to Also note, that Getting special files// get profile directory var file = Components.classes["@mozilla.org/file/directory_service;1"]. getService(Components.interfaces.nsIProperties). get("ProfD", Components.interfaces.nsIFile); Here are some strings you can put in place of
Look in the Source for other strings available: [1] [2]. User input via nsIFilePickerSee Dev : nsIFilePicker. nsIFile and path stringsYou can use // file is nsIFile var ios = Components.classes["@mozilla.org/network/io-service;1"]. getService(Components.interfaces.nsIIOService); var fileHandler = ios.getProtocolHandler("file"). QueryInterface(Components.interfaces.nsIFileProtocolHandler); var URL = fileHandler.getURLSpecFromFile(file); To load from file://, http://, chrome://, resource:// and other URLs directly, use Note: do not use Also note that generally you don't need to use Storing nsILocalFile in preferencesThe following two snippets show the right way to store a file path in user preferences (more about preferences in Mozilla): Absolute path (nsILocalFile)To store arbitrary path in user preferences, use this code. // |file| is nsILocalFile // 1. Write path to prefs var prefs = Components.classes["@mozilla.org/preferences-service;1"]. getService(Components.interfaces.nsIPrefService). getBranch("extensions.myext."); prefs.setComplexValue("filename", Components.interfaces.nsILocalFile, file); // 2. Read path from prefs var file = prefs.getComplexValue("filename", Components.interfaces.nsILocalFile); Relative path (nsIRelativeFilePref)To store paths relative to one of the predefined folders listed above, for example file relative to profile folder, use the following code: // 1. Write to prefs var relFile = Components.classes["@mozilla.org/pref-relativefile;1"] .createInstance(Components.interfaces.nsIRelativeFilePref); relFile.relativeToKey = "ProfD"; // or any other string listed above relFile.file = file; // |file| is nsILocalFile prefs.setComplexValue("filename", Components.interfaces.nsIRelativeFilePref, relFile); // 2. Read from prefs var value = prefs.getComplexValue("filename", Components.interfaces.nsIRelativeFilePref); // |value.file| is the file. Navigating with nsIFileGet a file in given directoryAssume, Note: avoid using Enumerating files in given directoryThe snippet below makes an array of // file is the given directory (nsIFile) var entries = file.directoryEntries; var array = []; while(entries.hasMoreElements()) { var entry = entries.getNext(); entry.QueryInterface(Components.interfaces.nsIFile); array.push(entry); } Reading from a fileSimpleNote: this code may have to be changed - see bug 278786 // |file| is nsIFile var data = ""; var fstream = Components.classes["@mozilla.org/network/file-input-stream;1"] .createInstance(Components.interfaces.nsIFileInputStream); var sstream = Components.classes["@mozilla.org/scriptableinputstream;1"] .createInstance(Components.interfaces.nsIScriptableInputStream); fstream.init(file, 1, 0, false); sstream.init(fstream); data += sstream.read(-1); sstream.close(); fstream.close(); alert(data); Line by line// open an input stream from file var istream = Components.classes["@mozilla.org/network/file-input-stream;1"] .createInstance(Components.interfaces.nsIFileInputStream); istream.init(file, 0x01, 0444, 0); istream.QueryInterface(Components.interfaces.nsILineInputStream); // read lines into array var line = {}, lines = [], hasmore; do { hasmore = istream.readLine(line); lines.push(line.value); } while(hasmore); istream.close(); // do something with read data alert(lines); AsynchronouslyThis will allow you to read a file without locking up the UI thread. // |file| is nsIFile var ios = Components.classes["@mozilla.org/network/io-service;1"] .getService(Components.interfaces.nsIIOService); var fileURI = ios.newFileURI(file); var channel = ios.newChannelFromURI(fileURI); var observer = { onStreamComplete : function(aLoader, aContext, aStatus, aLength, aResult) { alert(aResult); } }; var sl = Components.classes["@mozilla.org/network/stream-loader;1"] .createInstance(Components.interfaces.nsIStreamLoader); sl.init(channel, observer, null); Writing to a file// file is nsIFile, data is a string var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"] .createInstance(Components.interfaces.nsIFileOutputStream); // use 0x02 | 0x10 to open file for appending. foStream.init(file, 0x02 | 0x08 | 0x20, 0664, 0); // write, create, truncate foStream.write(data, data.length); foStream.close(); Flags parameter to the flags: The file status flags. It is a bitwise OR of the following bit flags (only one of the first three flags below may be used):
|