web-dev-qa-db-ja.com

ファイルを解凍する

Webブラウザを使用して、クライアント側で OpenOffice ファイル、.odtおよび.odpを表示したい。

これらのファイルは圧縮ファイルです。 Ajaxを使用すると、サーバーからこれらのファイルを取得できますが、これらは圧縮ファイルです。 JavaScript を使用して解凍する必要があり、inflate.jsを使用してみました http://www.onicos.com/staff/iz/amuse/javascript/expert/inflate.txt 、ただし成功しません。

これどうやってするの?

69
user69260

JavaScriptで解凍プログラムを書きました。できます。

Andy G.P. Naのバイナリファイルリーダー および notmasteryetの一部のRFC1951ロジックを拡張する に依存しています。 ZipFileクラスを追加しました。

作業例:
http://cheeso.members.winisp.net/Unzip-Example.htm (リンク切れ)

起源:
http://cheeso.members.winisp.net/srcview.aspx?dir=js-unzip (リンク切れ)

[〜#〜] nb [〜#〜]:リンクは無効です。新しいホストがすぐに見つかります。

ソースには、ZipFile.htmデモページと、zipfileクラス用、inflateクラス用、バイナリファイルリーダークラス用の3つの異なるスクリプトが含まれています。デモはjQueryとjQuery UIにも依存しています。 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));
    }
}
_

デモは2つのステップで機能します。readFile fnはクリックによってトリガーされ、Zipファイルを読み取るZipFileオブジェクトをインスタンス化します。読み取りが完了したときの非同期コールバックがあります(通常、適切なサイズのzipの場合は1秒以内に発生します)-このデモでは、コールバックはdoneReadingローカル変数に保持され、extractEntriesを呼び出します。提供されたZipファイルのすべてのコンテンツ。実際のアプリでは、おそらく抽出するエントリの一部を選択します(ユーザーが選択できるようにするか、プログラムで1つ以上のエントリを選択できます)。

extractEntries fnはすべてのエントリを反復処理し、各エントリでextract()を呼び出してコールバックを渡します。エントリの解凍には時間がかかります。zipファイル内のエントリごとに1秒以上かかる場合があります。これは、非同期が適切であることを意味します。抽出コールバックは、抽出されたコンテンツをページ上のjQueryアコーディオンに追加するだけです。コンテンツがバイナリの場合、そのようにフォーマットされます(表示されていません)。


動作しますが、ユーティリティは多少制限されていると思います。

一つには、非常に遅いです。 PKWareから140k AppNote.txtファイルを解凍するには、約4秒かかります。 .NETプログラムでは、同じ圧縮解除を.5秒未満で実行できます。 [〜#〜] edit [〜#〜]:Javascript ZipFileは、IE9およびChromeでこれよりもかなり高速に解凍されます。コンパイルされたプログラムよりもまだ遅いですが、通常のブラウザの使用ではかなり高速です。

別の場合:それはストリーミングを行いません。基本的に、zipファイルの内容全体をメモリに丸lurみします。 「実際の」プログラミング環境では、Zipファイルのメタデータ(たとえば、エントリごとに64バイト)のみを読み込み、必要に応じて他のデータを読み込んで解凍できます。私が知っている限り、javascriptのようにIOを実行する方法はありません。したがって、唯一のオプションはZip全体をメモリに読み込み、その中にランダムアクセスを行うことです。大きなZipファイルのシステムメモリに対する不合理な要求。小さなZipファイルの場合はそれほど問題ではありません。

また、「一般的な」Zipファイルを処理しません-Zip暗号化、WinZip暗号化、Zip64など、unzipに実装する必要のない多くのZipオプションがあります。 UTF-8エンコードされたファイル名、 等々。 ([〜#〜] edit [〜#〜]-UTF-8でエンコードされたファイル名を処理します)。ただし、ZipFileクラスは基本を処理します。これらのことのいくつかは実装するのが難しくないでしょう。 Javascriptで AES暗号化クラス を使用しています。暗号化をサポートするために統合できます。 Zip64のサポートは、Javascriptのほとんどのユーザーにとっておそらく役に立たないでしょう。4GBを超えるzipファイルをサポートすることを目的としているためです。

また、バイナリコンテンツの解凍のケースもテストしませんでした。現在、テキストを解凍します。圧縮されたバイナリファイルがある場合は、ZipFileクラスを編集して適切に処理する必要があります。私はそれをきれいに行う方法を理解していませんでした。 現在、バイナリファイルも実行しています。


[〜#〜] edit [〜#〜]-JS unzipライブラリとデモを更新しました。テキストに加えて、バイナリファイルを実行するようになりました。復元力と汎用性を高めました。テキストファイルの読み取り時に使用するエンコードを指定できるようになりました。また、デモが拡張されています-特に、ブラウザーでXLSXファイルを解凍することが示されています。

だから、私はそれが限られた有用性と興味があると思うが、それは動作します。 Node.jsで機能すると思います。

61
Cheeso

Zip.js を使用していますが、非常に便利なようです。一見の価値があります!

nzip demo などを確認してください。

24
Dani bISHOP

jszip は非常に便利です。これまでは読書にのみ使用してきましたが、作成/編集機能も備えています。

コード的にはこのように見えます

var new_Zip = new JSZip();
new_Zip.load(file);
new_Zip.files["doc.xml"].asText() // this give you the text in the file

私が気づいたことの1つは、ファイルがバイナリストリーム形式でなければならないことです(FileReader()の.readAsArrayBufferを使用して読み取り、そうでない場合、破損したZipファイルがある可能性があるというエラーが表示されていました)

11
AlvaroFG

コード例は 著者サイトの で与えられます。 babelfish を使用してテキストを翻訳できます(日本語から英語)。

私が日本語を理解している限り、このZip inflateコードは、ZipアーカイブではなくZipデータ(ストリーム)をデコードするためのものです。

2
OcuS

私もそのためのクラスを書きました。 http://blog.another-d-mention.ro/programming/read-load-files-from-Zip-in-javascript/ javascript/css/imagesなどの基本的なアセットを直接読み込むことができますクラスメソッドを使用してZipから。それが役に立てば幸い

2
TheBrain

他の形式もサポートする必要がある場合、または優れたパフォーマンスが必要な場合は、これを使用できます WebAssembly library

それはベースに約束されており、スレッドにWebWorkersを使用し、APIは実際にはシンプルなESモジュールです

2
MySqlError

「Binary Tools for JavaScript」を作成しました。これは、unzip、unrar、untarの機能を含むオープンソースプロジェクトです。 https://github.com/codedread/bitjs

私のコミックブックリーダーで使用: https://github.com/codedread/kthoom (オープンソース)。

HTH!

2
codedread