web-dev-qa-db-ja.com

javascriptを使用して、アップロードされたファイルを複数のチャンクに分割します

複数のファイルとしてアップロードする前に、ブラウザのフロントエンドでテキスト/データファイルを分割する方法を探しています。私の制限はアップロードごとに40KBです。したがって、ユーザーが400KBのファイルをアップロードすると、サーバーにアップロードする前に、このファイルがフロントエンドで10個の個別のチャンクまたは10個の個別のファイルに分割されます。

現在、このファイルをbase64形式の文字列に変換し、この文字列を40KBで分割して、10個の個別のチャンクに変換しています。そこから、chunk-1-of-10、chunk-2-of-10のファイル名のように各チャンクをアップロードします...

これらのファイルをプルダウンするときは、これらすべてのチャンクを連結して、base64からファイル形式に逆変換します。

これを行うためのより良い方法はありますか?ゼロから作成するのではなく、これらすべてを処理するライブラリはありますか? base64ルートがこれを行うための最良の方法であるかどうかはわかりません。

8

Base64を使用してFileReaderでコンテンツをRAMに読み込む必要はありません。アップロードする必要があるもののサイズが増えるだけです。

Blob.slice を使用してチャンクを取得します

// simulate a file from a input
const file = new File(['a'.repeat(1000000)], 'test.txt')

const chunkSize = 40000
const url = 'https://httpbin.org/post'

for (let start = 0; start < file.size; start += chunkSize) {
  const chunk = file.slice(start, start + chunkSize + 1)
  const fd = new FormData()
  fd.append('data', chunk)

  await fetch(url, {method: 'post', body: fd}).then(res => res.text())
}
6
Endless

FileReaderを使用してバイナリとして送信することで、base64エンコードの必要性を回避できます。

const url = 'http://www.example.com/upload';

document.getElementById('file-uploader').addEventListener('change', function(e) {
    const size = 40000;
    var reader = new FileReader();
    var buf;
    var file = document.getElementById('file-uploader').files[0];
    reader.onload = function(e) {
        buf = new Uint8Array(e.target.result);
        for (var i = 0;  i < buf.length; i += size) {
            var fd = new FormData();
            fd.append('fname', [file.name, i+1, 'of', buf.length].join('-'));
            fd.append('data', new Blob([buf.subarray(i, i + size)]));
            var oReq = new XMLHttpRequest();
            oReq.open("POST", url, true);
            oReq.onload = function (oEvent) {
               // Uploaded.
            };
            oReq.send(fd);
        }
    }
      
    reader.readAsArrayBuffer(file);
});
<input type="file" id="file-uploader"/>
3
dave