web-dev-qa-db-ja.com

JavaScriptを使用して大きなデータストリーム(> 1Gb)をダウンロードする

データをストリーミングできるかどうか疑問に思いましたJavaScriptからブラウザーのダウンロードマネージャーへ

Webrtcを使用して、ブラウザーから別のブラウザーに(ファイル> 1Gbから)データをストリーミングします。受信側では、このすべてのデータを(arraybuffer ...としてデータが本質的にまだチャンクとして)メモリに格納し、ユーザーがそれをダウンロードできるようにしたいと考えています。

問題: Blobオブジェクトの最大サイズは約600 Mb(ブラウザによって異なります)であるため、チャンクからファイルを再作成できません。これらのチャンクをストリーミングしてブラウザが直接ダウンロードできるようにする方法はありますか?

12
Brian

@ guest271314のアドバイスに従って、 StreamSaver.js をプロジェクトに追加し、Chromeで1GBを超えるファイルを正常に受信しました。ドキュメントによると、最大15GBのファイルで機能するはずですが、それ以前にブラウザがクラッシュしました(最大ファイルサイズは約4GBでした)。

注I:Blobの最大サイズの制限を回避するために、<a></a>のhrefフィールドにデータを手動で追加しようとしましたが、失敗しました約600MBのファイルで...

注II:驚くほど思われるかもしれませんが、createObjectURLを使用した基本的なテクニックは、最大4GBのファイルに対してFirefoxで完全に正常に機能します。

3
Brian

aPIまたはURLから大きなファイルBLOBをフェッチする場合は、streamsaverを使用できます。

npm install streamsaver

その後、あなたはこのようなことをすることができます

import { createWriteStream } from 'streamsaver';

export const downloadFile = (url, fileName) => {
  return fetch(url).then(res => {
    const fileStream = createWriteStream(fileName);
    const writer = fileStream.getWriter();
    if (res.body.pipeTo) {
      writer.releaseLock();
      return res.body.pipeTo(fileStream);
    }

    const reader = res.body.getReader();
    const pump = () =>
      reader
        .read()
        .then(({ value, done }) => (done ? writer.close() : writer.write(value).then(pump)));

    return pump();
  });
};

次のように使用できます:

const url = "http://urltobigfile";
const fileName = "bigfile.Zip";

downloadFile(url, fileName).then(() => { alert('done'); });
2
David