nsIZipWriter 编辑
modules/libjar/zipwriter/public/nsIZipWriter.idl
Scriptable This interface provides an easy way for scripts to archive data in the Zip file format. Operations on the archive can be performed one by one, or queued for later execution. 1.0 66 Introduced Gecko 1.9 Inherits from: 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.
Note: Although it is not necessary to add directory entries in order to add file entries within them, some Zip utilities may have problems with that, so it may be best to add the directory entries explicitly first.Implemented by: @mozilla.org/zipwriter;1
. To create an instance, use:
var zipWriter = Components.classes["@mozilla.org/zipwriter;1"] .createInstance(Components.interfaces.nsIZipWriter);
Method overview
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); |
Attributes
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. |
Constants
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. |
Methods
addEntryChannel()
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 );
Parameters
aZipEntry
- The path of the file entry to add to the Zip file. This is the path it will be located at within the Zip file. Note: You must use forward slashes ('/') in the path.
aModTime
- The modification time of the entry in microseconds.
aCompression
- One of the compression constants, indicating the compression method to use.
aChannel
- The channel from which to get the data.
aQueue
- If
true
, the operation is queued for later execution. Iffalse
, the operation is performed immediately. Will be performed whenprocessQueue()
is called.
Exceptions thrown
NS_ERROR_NOT_INITIALIZED
- No Zip file is open.
NS_ERROR_FILE_ALREADY_EXISTS
- The specified path already exists in the Zip file.
NS_ERROR_IN_PROGRESS
- The Zip writer is already performing another operation.
addEntryDirectory()
Adds a new directory entry to the Zip file. If aZipEntry does not end with "/" then it will be added.
Note: Although it is not necessary to add directory entries in order to add file entries within them, some Zip utilities may have problems with that, so it may be best to add the directory entries explicitly first.void addEntryDirectory( in AUTF8String aZipEntry, in PRTime aModTime, in boolean aQueue );
Parameters
aZipEntry
- The path of the directory entry to add to the Zip file.Note: You must use forward slashes in the path. (A forward slash is '/')
Detail: 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".
aModTime
- The modification time of the entry in microseconds.
aQueue
- If
true
, the operation is queued for later execution. Iffalse
, the operation is performed immediately. Will be performed whenprocessQueue()
is called.
Exceptions thrown
NS_ERROR_NOT_INITIALIZED
- No Zip file is open.
NS_ERROR_FILE_ALREADY_EXISTS
- The specified path already exists in the Zip file.
NS_ERROR_IN_PROGRESS
- The Zip writer is already performing another operation.
addEntryFile()
Adds 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 );
Parameters
aZipEntry
- The path of the file entry to add to the Zip file. This is the path it will be located at within the Zip file. Note: You must use forward slashes in the path. (A forward slash is '/')
aCompression
- One of the compression constants, indicating the compression method to use.
aFile
- The file from which to get the data and modification time.
aQueue
- If
true
, the operation is queued for later execution. Iffalse
, the operation is performed immediately. Will be performed whenprocessQueue()
is called.
Exceptions thrown
NS_ERROR_NOT_INITIALIZED
- No Zip file is open.
NS_ERROR_FILE_ALREADY_EXISTS
- The specified path already exists in the Zip file.
NS_ERROR_IN_PROGRESS
- The Zip writer is already performing another operation.
NS_ERROR_FILE_NOT_FOUND
- If file does not exist.
addEntryStream()
Adds 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 );
Parameters
aZipEntry
- The path of the file entry to add to the Zip file. This is the path it will be located at within the Zip file. Note: You must use forward slashes in the path.
aModTime
- The modification time of the entry in microseconds.
aCompression
- One of the compression constants, indicating the compression method to use.
aStream
- The input stream from which to get the data.
aQueue
- If
true
, the operation is queued for later execution. Iffalse
, the operation is performed immediately. Will be performed whenprocessQueue()
is called.
Exceptions thrown
NS_ERROR_NOT_INITIALIZED
- No Zip file is open.
NS_ERROR_FILE_ALREADY_EXISTS
- The specified path already exists in the Zip file.
NS_ERROR_IN_PROGRESS
- The Zip writer is already performing another operation.
close()
Closes the Zip file.
void close();
Parameters
None.
Exceptions thrown
NS_ERROR_NOT_INITIALIZED
- No Zip file is open.
NS_ERROR_IN_PROGRESS
- The Zip writer is already performing another operation.
Other errors may be thrown if a failure to complete the Zip file occurs.
getEntry()
Returns a specified entry or null
if there is no such entry in the current Zip file.
nsIZipEntry getEntry( in AUTF8String aZipEntry );
Parameters
aZipEntry
- The path of the file entry to get.
Return value
An nsIZipEntry
object describing the specified entry, or null
if there is no such entry.
hasEntry()
Determines whether or not a specific entry exists in the Zip file.
boolean hasEntry( in AUTF8String aZipEntry );
Parameters
aZipEntry
- The path of the file entry to check for.
Return value
true
if there is an entry with the given path in the Zip file, otherwise returns false
.
open()
Opens the specified Zip file.
void open( in nsIFile aFile, in PRInt32 aIoFlags );
Parameters
aFile
- The Zip file to open.
aIoFlags
- The open flags for the Zip file, from
prio.h
.
Exceptions thrown
NS_ERROR_ALREADY_INITIALIZED
- A Zip file is already open.
NS_ERROR_INVALID_ARG
- The
aFile
parameter isnull
. NS_ERROR_FILE_NOT_FOUND
- The specified file was not found and the flags didn't permit creating it. Or the directory for the file does not exist.
NS_ERROR_FILE_CORRUPTED
- The specified file is not a recognizable Zip file.
Other errors may be thrown upon failing to open the file, such as if the file is corrupt or in an unsupported format.
processQueue()
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 );
Parameters
aObserver
- The observer to receive notifications from the queue.
aContext
- The context to pass to the observer.
Exceptions thrown
NS_ERROR_NOT_INITIALIZED
- No Zip file is open.
NS_ERROR_IN_PROGRESS
- The queue is already in progress.
removeEntry()
Removes an entry from the Zip file.
void removeEntry( in AUTF8String aZipEntry, in boolean aQueue );
Parameters
aZipEntry
- The path of the entry to remove from the Zip file.
aQueue
true
to place the remove operation into the queue, orfalse
to process it at once. Will be performed whenprocessQueue()
is called.
Exceptions thrown
NS_ERROR_NOT_INITIALIZED
- No Zip file is open.
NS_ERROR_IN_PROGRESS
- The queue is already in progress.
NS_ERROR_FILE_NOT_FOUND
- No entry with the given path exists.
Other errors may occur if updating the Zip file fails.
Example
Adding a comment to a Zip file
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.
Adding a file to a Zip archive
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.
Recursively Add All Contents of a Directory to Zip File
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}; ///wiki/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 /wiki/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()
}
Other examples
For other examples, take a look at the unit tests in the source tree:
See also
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论