私はJavascriptで解凍を書きました。できます。
これは、Andy GP Naのバイナリファイルリーダーと、notmasteryetのRFC1951インフレートロジックに依存しています。ZipFileクラスを追加しました。
実例:
http ://cheeso.members.winisp.net/Unzip-Example.htm (リンク切れ)
ソース:
http ://cheeso.members.winisp.net/srcview.aspx?dir = js-unzip (デッドリンク)
注意:リンクは無効です。すぐに新しいホストを見つけます。
ソースには、ZipFile.htmデモページと、3つの異なるスクリプトが含まれています。1つはzipfileクラス用、1つはinflateクラス用、もう1つはバイナリファイルリーダークラス用です。デモはjQueryとjQueryUIにも依存しています。js-zip.zipファイルをダウンロードするだけで、必要なソースがすべてそこにあります。
Javascriptでのアプリケーションコードは次のようになります。
// In my demo, this gets attached to a click event.
// it instantiates a ZipFile, and provides a callback that is
// invoked when the zip is read. This can take a few seconds on a
// large zip file, so it's asynchronous.
var readFile = function(){
$("#status").html("<br/>");
var url= $("#urlToLoad").val();
var doneReading = function(zip){
extractEntries(zip);
};
var zipFile = new ZipFile(url, doneReading);
};
// this function extracts the entries from an instantiated zip
function extractEntries(zip){
$('#report').accordion('destroy');
// clear
$("#report").html('');
var extractCb = function(id) {
// this callback is invoked with the entry name, and entry text
// in my demo, the text is just injected into an accordion panel.
return (function(entryName, entryText){
var content = entryText.replace(new RegExp( "\\n", "g" ), "<br/>");
$("#"+id).html(content);
$("#status").append("extract cb, entry(" + entryName + ") id(" + id + ")<br/>");
$('#report').accordion('destroy');
$('#report').accordion({collapsible:true, active:false});
});
}
// for each entry in the zip, extract it.
for (var i=0; i<zip.entries.length; i++) {
var entry = zip.entries[i];
var entryInfo = "<h4><a>" + entry.name + "</a></h4>\n<div>";
// contrive an id for the entry, make it unique
var randomId = "id-"+ Math.floor((Math.random() * 1000000000));
entryInfo += "<span class='inputDiv'><h4>Content:</h4><span id='" + randomId +
"'></span></span></div>\n";
// insert the info for one entry as the last child within the report div
$("#report").append(entryInfo);
// extract asynchronously
entry.extract(extractCb(randomId));
}
}
デモはいくつかのステップで機能しreadFile
ます。fnはクリックによってトリガーされ、zipファイルを読み取るZipFileオブジェクトをインスタンス化します。読み取りが完了したときの非同期コールバックがあります(通常、適度なサイズのzipの場合は1秒未満で発生します)-このデモでは、コールバックはdoneReadingローカル変数で保持されますextractEntries
。 ZIPファイル。実際のアプリでは、抽出するエントリの一部を選択する可能性があります(ユーザーが選択できるようにするか、プログラムで1つ以上のエントリを選択できるようにします)。
fnはextractEntries
すべてのエントリを繰り返し処理し、extract()
各エントリを呼び出してコールバックを渡します。エントリの解凍には時間がかかります。zipファイルのエントリごとに1秒以上かかる場合があります。これは、非同期が適切であることを意味します。抽出コールバックは、抽出されたコンテンツをページ上のjQueryアコーディオンに追加するだけです。コンテンツがバイナリの場合、そのようにフォーマットされます(表示されていません)。
動作しますが、効用はやや限られていると思います。
一つには、それは非常に遅いです。PKWareから140kAppNote.txtファイルを解凍するのに約4秒かかります。同じ解凍は、.NETプログラムで.5秒未満で実行できます。 編集:Javascript ZipFileは、IE9とChromeで、これよりもかなり速く解凍されます。コンパイルされたプログラムよりもまだ低速ですが、通常のブラウザの使用には十分高速です。
別の場合:ストリーミングは行いません。基本的に、zipファイルの内容全体をメモリに丸呑みします。「実際の」プログラミング環境では、zipファイルのメタデータ(たとえば、エントリあたり64バイト)のみを読み込んでから、必要に応じて他のデータを読み込んで解凍することができます。私の知る限り、JavaScriptでそのようなIOを実行する方法はありません。したがって、唯一のオプションは、zip全体をメモリに読み込み、ランダムアクセスを実行することです。これは、大きなzipファイルのシステムメモリに不当な要求を課すことを意味します。小さいzipファイルではそれほど問題にはなりません。
また、「一般的なケース」のzipファイルは処理されません。ZIP暗号化、WinZip暗号化、zip64、UTF-8でエンコードされたファイル名など、解凍ツールに実装する必要がなかったzipオプションがたくさんあります。の上。(編集-UTF-8でエンコードされたファイル名を処理するようになりました)。ただし、ZipFileクラスは基本を処理します。これらのいくつかは、実装するのが難しくないでしょう。JavascriptにAES暗号化クラスがあります。暗号化をサポートするために統合することができます。Zip64のサポートは、4 GBを超えるzipファイルをサポートすることを目的としているため、Javascriptのほとんどのユーザーにとっておそらく役に立たないでしょう。ブラウザーでそれらを抽出する必要はありません。
また、バイナリコンテンツを解凍するケースもテストしていません。現在、テキストを解凍します。zip形式のバイナリファイルがある場合は、ZipFileクラスを編集して適切に処理する必要があります。私はそれをきれいに行う方法を理解していませんでした。 現在、バイナリファイルも実行しています。
編集-JS解凍ライブラリとデモを更新しました。テキストに加えて、バイナリファイルを実行するようになりました。より弾力性があり、より一般的になりました。テキストファイルを読み取るときに使用するエンコーディングを指定できるようになりました。また、デモが拡張されています。特に、ブラウザでXLSXファイルを解凍する方法が示されています。
ですから、有用性と関心は限られていると思いますが、機能します。Node.jsで動作すると思います。