2016-08-31 15 views
7

1GBファイルをダウンロードするXHRオブジェクトがあります。 Javascriptの大きなblobファイル

function getFile(callback) 
{ 
    var xhr = new XMLHttpRequest(); 
    xhr.onload = function() { 
     if (xhr.status == 200) { 
      callback.apply(xhr); 
     }else{ 
      console.log("Request error: " + xhr.statusText); 
     } 
    }; 

    xhr.open('GET', 'download', true); 
    xhr.onprogress = updateProgress; 
    xhr.responseType = "arraybuffer"; 
    xhr.send(); 
} 

しかし、ファイルのAPIも、労働者 それはメモリ不足のスローからメモリにすべてのことをロードすることはできません...

btn.addEventListener('click', function() { 
    getFile(function() { 
     var worker = new Worker("js/saving.worker.js"); 
     worker.onmessage = function(e) { 
      saveAs(e.data); // FileSaver.js it creates URL from blob... but its too large 
     }; 

     worker.postMessage(this.response); 
    }); 
}); 

ウェブワーカー

onmessage = function (e) { 
    var view = new DataView(e.data, 0); 
    var file = new File([view], 'file.zip', {type: "application/zip"}); 
    postMessage('file'); 
}; 

私は」ファイルを圧縮しようとしていない場合、このファイルはすでにサーバーから圧縮されています。

私はのIndexedDBに最初にそれを保存すると思ったけど、私はすぐに、私は、範囲バイトで要求を行う場合でも、BLOBを読み込むか、とにかく提出する必要があるでしょうか遅い私はこの巨大なブロブを構築する必要があります。..

私はblob:URLを作成してブラウザにダウンロードされた後にユーザに送信します。

Google Chrome用のFileSystem APIを使用しますが、Firefox用のものを作りたいと思っています。

Google ChromeのFileSystemと同じ機能を実行するには、firefoxの拡張機能をビルドする必要がありますか? AJAXと


Ubuntuの32ビット

+0

それが仕事でしたができれば良いでしょう、これを確認することはできませんか?エラーは、私には馴染みがあり、「メモリ不足」です。 – Hydro

+0

うーん、それは大規模なリアリティだけのために働いた –

+0

うーん... btnクリックイベントが発生したときに何か警告することはできますか?エラーがスローされたら、ここに届いたアラートの量をお知らせください – Hydro

答えて

6

読み込み1GBの+だけダウンロードの進行状況を監視し、メモリを埋めるために便利ではありません。

代わりに、Content-Dispositionヘッダーを付けたファイルを送信してファイルを保存します。


しかし、進捗状況を監視する方法があります。オプション1は、取得リクエストで通常ダウンロードしている間にどれだけダウンロードしたかを示す2番目のwebsocketを持つことです。もう1つのオプションについては、後で詳しく説明します。


私は会話でBlinksサンドボックスファイルシステムを使用する方法について話したことがあります。それにはいくつかの欠点があります。永続ストレージを使用する場合は、アクセス許可が必要な場合があります。使用可能なディスクの20%しか残されていません。また、クロムに空き領域を確保する必要がある場合は、最新のファイルに最後に使用された一時記憶領域のドメインをすべて破棄します。それはプライベートモードでは動作しません。
は、それはそれのためのサポートをドロップされており、他のブラウザで終わることがないことは言うまでもありません - しかし、多くのサイトはまだそれ


でこれを処理するための唯一の方法に依存するので、彼らはほとんどの場合、それを削除しません。大きなファイルはストリームにあります。だからこそ私はStreamSaverを作成しました。これはBlink(chrome &オペラ)ATMでしか動作しませんが、最終的にwhatwg仕様で他のブラウザにサポートされ、標準としてバックアップされます。私はあなたがチャンクにファイルを分割し、後でそれらを一緒にマージし、その後のIndexedDBに保存している場合である理論を持っている、それが動作します

fetch(url).then(res => { 
    // One idea is to get the filename from Content-Disposition header... 
    const size = ~~res.headers.get('Content-Length') 
    const fileStream = streamSaver.createWriteStream('filename.zip', size) 
    const writeStream = fileStream.getWriter() 
    // Later you will be able to just simply do 
    // res.body.pipeTo(fileStream) 
    // instead of pumping 

    const reader = res.body.getReader() 
    const pump =() => reader.read() 
     .then(({ value, done }) => { 
      // here you know how large the value (chunk) is and you can 
      // figure out the download speed/progress when comparing it to the size 

      return done 
       ? writeStream.close() 
       : writeStream.write(value).then(pump) 
     ) 

    // Start the reader 
    pump().then(() => 
     console.log('Closed the stream, Done writing') 
    ) 
}) 

これは、任意のメモリ

+0

firefoxのためにますます同じことをする拡張を作成できますか?回避策はありますか? –

+0

ほとんど何でもFirefox拡張機能で可能ですので、私はそう思います。しかし、私は人々がそれをインストールするとは思わない: - あなたは代わりにストリームを実装するfirefoxの助けを借りて貢献することができます:-) – Endless

4

を取ることはありません

ブロブは、それがより多くのあなたがのIndexedDBに保存して、このような何か(を使用して操作を行う場合は、ファイルは意味 enter image description here

から読み取ることができますへのポインタのようなものだ...データで構成されていませんまたは代替)

finalBlob = new Blob([blob_A_fromDB, blob_B_fromDB]) 
saveAs(finalBlob, 'filename.zip') 

しかし、私はそれをテストしていないので、私はあなたが小さい\ *。zipファイルをダウンロードした際に他の誰かが

+1

私はそれをテストし始めました。そして、私はそれが動作すると思う:)私はこの問題を見直すのを助ける:https://github.com/jimmywarting/StreamSaver.js/pull/18 – Endless

+0

私も試していたが、私は時間がない:/ 開発が遅すぎる –

+0

から450MBのファイルはうまくいった –

関連する問題