1

JSZipさまざまなダウンストリーム ファイルからファイルに zip ファイルを作成する方法を検討しています。これが私がやろうとしていることの擬似コードです:

function* handler () {
    const ids = this.request.body.ids;

    const zip = new JSZip();
    for (let i = 0; i < ids; i++) {
        const r = yield request.get('/some/remote/service/' + ids[i]);
        zip.file(ids[i], r.body);
    }
    this.body = zip.nodeStream():
}  

ただし、おそらくこれには、すべてのファイルの内容を一度にメモリに入れる必要があり、すべてのファイルがダウンロードされるまでストリーミングを開始しません。

次のようなことを行うことで、ダウンロード時間を最適化できることに気付きました。

const allFiles = yield ids.map((id) => request.get('/some/remote/service/' + id));

for (let i = 0; i < ids.length; i++) zip.file(ids[i], allFiles[i]);

しかし、主に、一度に1つのファイルのみをメモリに保持し、結果をzip経由でクライアントにストリーミングする方法を望んでいます。それは可能JSZipですか?

4

1 に答える 1

0

一度に1つのファイルのみをメモリに保持し、結果をzip経由でクライアントにストリーミングする方法を望んでいます。それは可能JSZipですか?

欠点がないわけではありません。JSZip は、(まだ) ジェネレーターまたは関数をファイルのコンテンツとして受け入れません。ファイルの完全なコンテンツ、その約束、またはストリームが必要です。これは、コンテンツが実際に必要な最後の瞬間に API 呼び出しを (まだ) トリガーできないことを意味します。

ストリームを ( でzip.file("filename.txt", myStream)) 追加すると、JSZip はそれを一時停止し、何かがそれを使用するのを待ちます (zip.generateNodeStream()たとえば、または getter への呼び出し)。

したがって、(現在の v3.1.2 で) できることは、メモリ使用量を制限するために、すべてのリソースをストリームとして追加し、 を呼び出すことzip.generateNodeStream({streamFiles:true})です。主な欠点は、Web サービスへの接続を開くと、最初のファイルをストリーミングしているときに (たとえば、最後のファイルで) タイムアウトになる可能性があることです (または.pause()、入力ストリームでの処理方法によってはさらに悪い)。

と質問のコメントについてstreamFiles: zip 形式はストリーミングに適しています。ドキュメントで述べたように、streamFilesオプションは、zip ファイル内のファイルのサイズ/crc32 が書き込まれる場所を決定します: データの前 (ただし、それらを計算するために一時的にファイルをメモリに保持する必要があります) またはデータの後 (すべてをストリーミングし、計算された値を最後に置きます)。

于 2016-08-29T22:58:48.020 に答える