nsIZipWriter を使ってフォルダ丸ごと圧縮

前提

・Firefox 21~24.0a1
・変数 srcDir は圧縮元フォルダの nsILocalFile オブジェクト
・変数 zipFile は圧縮先ファイルの nsILocalFile オブジェクト
srcDir の中身のファイルをすべて圧縮して新規のアーカイブ zipFile を生成する

nsIZipWriter インスタンス生成

はじめに nsIZipWriter インスタンスを生成し、 open メソッドで圧縮先ファイルを開く。
圧縮率はデフォルト(レベル6)とする。

// |zipFile| is a nsILocalFile object corresponding to the zip file
var zipWriter = Cc["@mozilla.org/zipwriter;1"].createInstance(Ci.nsIZipWriter);
const PR_WRONLY = 0x02;
const PR_CREATE_FILE = 0x08;
zipWriter.open(zipFile, PR_WRONLY | PR_CREATE_FILE);
var zipLevel = Ci.nsIZipWriter.COMPRESSION_DEFAULT;

フォルダ/ファイルのエントリ追加

srcDir を起点に、フォルダ内のファイルへ再帰的にアクセスする。

(function(dir) {
    var fileEnum = dir.directoryEntries;
    while (fileEnum.hasMoreElements()) {
        var file = fileEnum.getNext().QueryInterface(Ci.nsILocalFile);
        if (file.isDirectory()) {
            // [ToDo]            
            // go to sub folder recursively
            arguments.callee.call(this, file);
        }
        else if (file.isFile()) {
            // [ToDo]            
        }
    }
}).call(this, srcDir);
// |srcDir| is a nsILocalFile object corresponding to the folder where will be archived

変数 file がフォルダなら、 addEntryDirectory でエントリを追加する。第3引数 false だと即座に圧縮される。
変数 file がファイルなら、 addEntryFile でエントリを追加する。第4引数 false だと即座に圧縮される。
変数 file が通常のフォルダでもファイルでもなく、ショートカット(シンボリックリンク)などの場合は何もしない。

エントリ名は、圧縮元フォルダを起点にした圧縮元ファイルのパス。例えば、圧縮元ファイルのパスが「C:UsersHogeSourceDirectoryAAABBBccc.txt」なら、エントリ名は「AAA/BBB/ccc.txt」となる。フォルダの場合はエントリ名の末尾に「/」を付ける。

        var entry = file.path.substr(srcDir.path.length + 1).replace("", "/", "g");
        if (file.isDirectory()) {
            entry += "/";
            zipWriter.addEntryDirectory(entry, file.lastModifiedTime * 1000, false);
            // go to sub folder recursively
            arguments.callee.call(this, file);
        }
        else if (file.isFile()) {
            zipWriter.addEntryFile(entry, zipLevel, file, false);
        }

最後に圧縮先ファイルを閉じる。

zipWriter.close();

processQueue を使って後からまとめて圧縮

addEntryDirectory, addEntryFile の最後の引数を true にすると、その時点では圧縮されず、後で processQueue メソッド呼び出し時にまとめて圧縮される。

        if (file.isDirectory()) {
            entry += "/";
            zipWriter.addEntryDirectory(entry, file.lastModifiedTime * 1000, true);
            arguments.callee.call(this, file);
        }
        else if (file.isFile()) {
            zipWriter.addEntryFile(entry, zipLevel, file, true);
        }

processQueue の第1引数には nsIRequestObserver オブジェクトを渡す。
nsIRequestObserver は最初のファイル圧縮前に呼び出される onStartRequest と、最後のファイル圧縮後に呼び出される onStopRequest メソッドを持つ。

    zipWriter.processQueue({
        onStartRequest: function(aReuqest, aContext) {
        },
        onStopRequest: function(aRequest, aContext) {
            zipWriter.close();
        },
    }, null);

TOP

TOP