2011/05/31

ZIPファイル内のファイルを解凍したり直接読み込む

NILScriptのZLibユニットに用意されているZIPクラスを利用すれば、ZIPファイルの圧縮や解凍を行なえます。

ZIPファイル内の全てのファイルを指定のディレクトリに解凍するには、以下のようにZIPクラスのextract()メソッドを使用します。
require('ZLib').ZIP.extract(zipfile, directory);

extractText()やextractBytes()メソッドでは、ZIPファイル内のファイルをローカルファイルに保存することなく直接変数に読み込むことが出来ます。
extractText()は文字列、extractBytes()はポインタオブジェクトを返します。
以下の例では、ZIPファイル内の「changelog.txt」の内容を表示します。
巨大なZIPファイル内の小さなファイルだけを利用したい場合などには、特に効率化が期待できます。
println(require('ZLib').ZIP.extractText('F:\\downloads\\nil.zip','changelog.txt'));


ZIPクラスのインスタンスオブジェクトを作成すれば、更新日時や拡張子などの条件に一致するファイルだけを解凍したり、ファイルの解凍や読み込みは行なわずにサイズや更新日時などの情報を取得して利用するなど、様々な処理を行なえます。
以下の例では、ZIPファイル内のファイルとローカルファイルを比較し、ZIPファイルにだけ存在するファイルやZIPファイル内の方が新しいファイルを列挙します。
var dir=Main.scriptDirectory;
var file="F:\\downloads\\nil.zip";
try{
    var zip=require('ZLib').ZIP.open(file);
    for(let f in zip.descendants){
        var lf=dir.file(f.path);
        if(f.isDirectory){
        }else if(!lf.exists){
            println('[new] '+f.path);
        }else if(f.time>lf.mtime){
            println('[updated] '+f.path);
        }
    }
}finally{
    free(zip);
}
ZIPオブジェクトのdescendantsプロパティで、ZIPファイル内の全てのファイルがZIPFile/ZIPDirectoryオブジェクトとして列挙できます。
ZIPDirectoryオブジェクトを判別するために、isDirectoryプロパティが用意されているので、これを利用して除外します。
「Main.scriptDirectory」などのDirectoryオブジェクトのfile()メソッドの引数にZIPFileオブジェクトのpathプロパティを指定すれば、ZIP内のパスに対応するローカルファイルのFileオブジェクトを得られます。
ZIPFileのtimeプロパティでは、更新日時をDateオブジェクトとして得られます。これをFileオブジェクトのmtimeプロパティと比較すれば、ファイルが新しいかどうかが分かります。

その他、ZIPFile/ZIPDirectoryオブジェクトには、指定のローカルファイルとして解凍するcopy()メソッドなどが用意されています。ZIP関連の機能の詳細は、NILScriptに同梱のdoc\ZLib.txtを参照して下さい。

0 件のコメント:

コメントを投稿