nsISupports
Last changed in Gecko 1.9 (Firefox 3)Once all the operations you wish to perform are added to the queue, a call to processQueue() will perform the operations in the order they were added to the queue. Operations performed on the queue throw any errors that occur out to the observer.
Attempting to perform a synchronous operation on the interface while the background queue is in progress will throw an NS_ERROR_IN_PROGRESS exception.
File and directory names should use slashes ("/") as separators and should not begin with a slash.
Implemented by: @mozilla.org/zipwriter;1. To create an instance, use:
var zipWriter = Components.classes["@mozilla.org/zipwriter;1"]
.createInstance(Components.interfaces.nsIZipWriter);
void addEntryChannel(in AUTF8String aZipEntry, in PRTime aModTime, in PRInt32 aCompression, in nsIChannel aChannel, in boolean aQueue); |
void addEntryDirectory(in AUTF8String aZipEntry, in PRTime aModTime, in boolean aQueue); |
void addEntryFile(in AUTF8String aZipEntry, in PRInt32 aCompression, in nsIFile aFile, in boolean aQueue); |
void addEntryStream(in AUTF8String aZipEntry, in PRTime aModTime, in PRInt32 aCompression, in nsIInputStream aStream, in boolean aQueue); |
void close(); |
nsIZipEntry getEntry(in AUTF8String aZipEntry); |
boolean hasEntry(in AUTF8String aZipEntry); |
void open(in nsIFile aFile, in PRInt32 aIoFlags); |
void processQueue(in nsIRequestObserver aObserver, in nsISupports aContext); |
void removeEntry(in AUTF8String aZipEntry, in boolean aQueue); |
| Attribute | Type | Description |
comment |
ACString |
Gets or sets the comment associated with the currently open Zip file.
Exceptions thrown
|
file |
|
The Zip file being written to. Read only. |
inQueue |
boolean |
true if operations are being performed in the background queue, or false if background operations are not in progress. Read only. |
| Constant | Value | Description |
COMPRESSION_NONE |
0 |
Do not compress the file. |
COMPRESSION_FASTEST |
1 |
Use the fastest compression method when adding the file to the archive. |
COMPRESSION_DEFAULT |
6 |
Use the default compression method when adding the file to the archive. |
COMPRESSION_BEST |
9 |
Use the best compression method when adding the file to the archive. |
Adds data from a channel to the Zip file. If the operation is performed on the queue then the channel will be opened asynchronously, otherwise the channel must support being opened synchronously.
void addEntryChannel( in AUTF8String aZipEntry, in PRTime aModTime, in PRInt32 aCompression, in nsIChannel aChannel, in boolean aQueue );
aZipEntryaModTimeaCompressionaChannelaQueuetrue, the operation is queued for later execution. If false, the operation is performed immediately. Will be performed when processQueue() is called.NS_ERROR_NOT_INITIALIZEDNS_ERROR_FILE_ALREADY_EXISTSNS_ERROR_IN_PROGRESSAdds a new directory entry to the Zip file. If aZipEntry does not end with "/" then it will be added.
void addEntryDirectory( in AUTF8String aZipEntry, in PRTime aModTime, in boolean aQueue );
aZipEntryDetail: This aZipEntry is very important, this example demonstrates its usage:
var zw = Cc['@mozilla.org/zipwriter;1'].createInstance(Ci.nsIZipWriter);
var myZipFile = fu.File('C:\\MyZipFile.zip'); //this file will be creatd in C drive
var pr = {PR_RDONLY: 0x01, PR_WRONLY: 0x02, PR_RDWR: 0x04, PR_CREATE_FILE: 0x08, PR_APPEND: 0x10, PR_TRUNCATE: 0x20, PR_SYNC: 0x40, PR_EXCL: 0x80};
zw.open(xpi, pr.PR_WRONLY | pr.PR_CREATE_FILE | pr.PR_TRUNCATE); //xpi file is created if not there, if it is there it is truncated/deleted
var fileToAddToZip = FileUtils.File('C:\\add this file.txt');
var saveInZipAs = 'blah.txt';
zw.addEntryFile(saveInZipAs, Ci.nsIZipWriter.COMPRESSION_NONE, fileToAddToZip, false);
In the above example, the file ("add this file.txt") located at "C:\add this file.txt" will be added to the zip file "C:\MyZipFile.zip", however in the zip file this file ("add this file.txt") will be named "blah.txt". If saveInZipAs was equal to "add this file.txt" then in the zip file it will also be named "add this file.txt"
Further Detail: This example gives futher detail on the importance of forward slashes
var fileToAddToZip = FileUtils.File('C:\\add this file.txt');
var saveInZipAs = 'sub folder/blah.txt'; //DO NOT USE BACKWARD SLASH for example do not do: 'sub folder\\blah.txt'. Using backward slash will not throw any errors but if this was an xpi file, firefox would not be able to read it properly.
zw.addEntryFile(saveInZipAs, Ci.nsIZipWriter.COMPRESSION_NONE, fileToAddToZip, false);
This example creates a folder in the zip called "sub folder" and then adds "C:\add this file.txt" to it, but it will be called "blah.txt".
aModTimeaQueuetrue, the operation is queued for later execution. If false, the operation is performed immediately. Will be performed when processQueue() is called.NS_ERROR_NOT_INITIALIZEDNS_ERROR_FILE_ALREADY_EXISTSNS_ERROR_IN_PROGRESSAdds a new file or directory to the Zip file. If the specified file is a directory, this call is equivalent to:
addEntryDirectory(aZipEntry, aFile.lastModifiedTime, aQueue);
void addEntryFile( in AUTF8String aZipEntry, in PRInt32 aCompression, in nsIFile aFile, in boolean aQueue );
aZipEntryaCompressionaFileaQueuetrue, the operation is queued for later execution. If false, the operation is performed immediately. Will be performed when processQueue() is called.NS_ERROR_NOT_INITIALIZEDNS_ERROR_FILE_ALREADY_EXISTSNS_ERROR_IN_PROGRESSNS_ERROR_FILE_NOT_FOUNDAdds data from an input stream to the Zip file.
void addEntryStream( in AUTF8String aZipEntry, in PRTime aModTime, in PRInt32 aCompression, in nsIInputStream aStream, in boolean aQueue );
aZipEntryaModTimeaCompressionaStreamaQueuetrue, the operation is queued for later execution. If false, the operation is performed immediately. Will be performed when processQueue() is called.NS_ERROR_NOT_INITIALIZEDNS_ERROR_FILE_ALREADY_EXISTSNS_ERROR_IN_PROGRESSCloses the Zip file.
void close();
None.
NS_ERROR_NOT_INITIALIZEDNS_ERROR_IN_PROGRESSOther errors may be thrown if a failure to complete the Zip file occurs.
Returns a specified entry or null if there is no such entry in the current Zip file.
nsIZipEntry getEntry( in AUTF8String aZipEntry );
aZipEntryAn nsIZipEntry object describing the specified entry, or null if there is no such entry.
Determines whether or not a specific entry exists in the Zip file.
boolean hasEntry( in AUTF8String aZipEntry );
aZipEntrytrue if there is an entry with the given path in the Zip file, otherwise returns false.
Opens the specified Zip file.
void open( in nsIFile aFile, in PRInt32 aIoFlags );
aFileaIoFlagsprio.h.NS_ERROR_ALREADY_INITIALIZEDNS_ERROR_INVALID_ARGaFile parameter is null.NS_ERROR_FILE_NOT_FOUNDNS_ERROR_FILE_CORRUPTEDOther errors may be thrown upon failing to open the file, such as if the file is corrupt or in an unsupported format.
Processes all queued items until the entire queue has been processed or an error occurs. The observer is notified when the first operation begins and when the last operation completes.
Any failures are passed to the observer.
The Zip writer will be busy until the queue is complete or an error halts processing of the queue early. In the event of an early failure, the remaining items stay in the queue; calling processQueue() again will continue where operations left off.
void processQueue( in nsIRequestObserver aObserver, in nsISupports aContext );
aObserveraContextNS_ERROR_NOT_INITIALIZEDNS_ERROR_IN_PROGRESSRemoves an entry from the Zip file.
void removeEntry( in AUTF8String aZipEntry, in boolean aQueue );
aZipEntryaQueuetrue to place the remove operation into the queue, or false to process it at once. Will be performed when processQueue() is called.NS_ERROR_NOT_INITIALIZEDNS_ERROR_IN_PROGRESSNS_ERROR_FILE_NOT_FOUNDOther errors may occur if updating the Zip file fails.
var zipWriter = Components.Constructor("@mozilla.org/zipwriter;1", "nsIZipWriter");
var zipW = new zipWriter();
zipW.open(myZipFilePath, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE);
zipW.comment = "This is a comment.";
zipW.close();
PR_RDWR and friends are constants that are not in any interface (see bug 433295), so for the code above to work you need something like:
const PR_RDONLY = 0x01; const PR_WRONLY = 0x02; const PR_RDWR = 0x04; const PR_CREATE_FILE = 0x08; const PR_APPEND = 0x10; const PR_TRUNCATE = 0x20; const PR_SYNC = 0x40; const PR_EXCL = 0x80;
See PR_Open Documentation or File I/O Snippets for details.
This code synchronously adds the file specified by the nsIFile theFile to the Zip archive.
var zipWriter = Components.Constructor("@mozilla.org/zipwriter;1", "nsIZipWriter");
var zipW = new zipWriter();
zipW.open(myZipFilePath, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE);
zipW.addEntryFile("Path/For/This/File/In/Zip Archive", Components.interfaces.nsIZipWriter.COMPRESSION_DEFAULT, theFile, false);
zipW.close();
The argument myZipFilePath isn't a path but rather it has to be an nsIFile instance specifying the location of the new zip file. The file need not exist, but the directory that contains it (nsIFile.parent) must exist.
This example below can be copied and pasted into your scratchpad, set the environment to "Browser" and can run. What it does is shows a File Picker dialog and asks you to pick a folder. Once you pick a folder, it will create a zip file inside this folder with the same name as the folder. It will then recursively go through all contents in the folder selected and add them into this zip file. This example is also a good of example of the in AUTF8String aZipEntry argument of addEntryFile and how it is used, this entry is very important, it is basically what to save the file as in the zip, you can take a file "blah.exe" and make it save in the zip as "hi and no extension".
var {Cc: classes, Ci: interfaces, Cu: utils} = Components;
var zw = Cc['@mozilla.org/zipwriter;1'].createInstance(Ci.nsIZipWriter);
var pr = {PR_RDONLY: 0x01, PR_WRONLY: 0x02, PR_RDWR: 0x04, PR_CREATE_FILE: 0x08, PR_APPEND: 0x10, PR_TRUNCATE: 0x20, PR_SYNC: 0x40, PR_EXCL: 0x80}; ///en-US/docs/PR_Open#Parameters
var fu = Cu.import('resource://gre/modules/FileUtils.jsm').FileUtils;
var fp = Cc['@mozilla.org/filepicker;1'].createInstance(Ci.nsIFilePicker);
fp.init(window, 'Select Directory to Compile', Ci.nsIFilePicker.modeGetFolder);
fp.appendFilters(Ci.nsIFilePicker.filterAll | Ci.nsIFilePicker.filterText);
var rv = fp.show();
if (rv == Ci.nsIFilePicker.returnOK) {
var dir = fp.file;
//dir must exist, as the user selected it. but note that if dir doesnt exist zw.open throws problems
//var path = fp.file.path; //returns C:\Users\3K2KYC1\Documents\prefs\prefs
var xpi = fu.File(dir.path + '\\' + dir.leafName + '.zip');
zw.open(xpi, pr.PR_RDWR | pr.PR_CREATE_FILE | pr.PR_TRUNCATE); //PR_TRUNCATE overwrites if file exists //PR_CREATE_FILE creates file if it dne //PR_RDWR opens for reading and writing
//recursviely add all
var dirArr = [dir]; //adds dirs to this as it finds it
for (var i=0; i<dirArr.length; i++) {
Cu.reportError('adding contents of dir['+i+']: ' + dirArr[i].leafName + ' PATH: ' + dirArr[i].path);
var dirEntries = dirArr[i].directoryEntries;
while (dirEntries.hasMoreElements()) {
var entry = dirEntries.getNext().QueryInterface(Ci.nsIFile); //entry is instance of nsiFile so here /en-US/docs/XPCOM_Interface_Reference/nsIFile
if (entry.path == xpi.path) {
Cu.reportError('skipping entry - will not add this entry to the zip file - as this is the zip itself: "' + xpi.path + '" leafName:"' + xpi.leafName + '"');
continue;
}
if (entry.isDirectory()) {
dirArr.push(entry);
}
var relPath = entry.path.replace(dirArr[0].path, ''); //need relative because we need to use this for telling addEntryFile where in the zip it should create it, and because zip is a copy of the directory
Cu.reportError('+' + relPath); //makes it relative to directory the parent dir (dir[0]) so it can succesfully populate files with same names but different folders in this parent dir, needed because recursviely going through all dirs
var saveInZipAs = relPath.substr(1); //need to get ride of the first '\' forward slash at start otherwise it puts every file added in a folder of its own.
saveInZipAs = saveInZipAs.replace(/\\/g,'/'); //remember MUST use forward slash (/)
Cu.reportError('--' + saveInZipAs);
zw.addEntryFile(saveInZipAs, Ci.nsIZipWriter.COMPRESSION_NONE, entry, false);
}
}
zw.close()
}
For other examples, take a look at the unit tests in the source tree: