Разделите загруженный файл на несколько частей, используя JavaScript - PullRequest
0 голосов
/ 01 мая 2018

Я ищу способ разбить любой текстовый файл / файл данных на внешнем интерфейсе в браузере перед загрузкой в ​​виде нескольких файлов. Мой лимит составляет 40 КБ на загрузку. Поэтому, если пользователь загружает файл размером 400 КБ, он перед тем, как загрузить его на сервер, разделит этот файл на 10 отдельных кусков или 10 отдельных файлов на внешнем интерфейсе.

В настоящее время я делаю это, преобразовывая этот файл в строку формата base64, а затем разделяю эту строку на 40 КБ, что дает 10 отдельных кусков. Оттуда я загружаю каждый чанк как с именем chunk-1-of-10, chunk-2-of-10 ...

При извлечении этих файлов я просто объединяю все эти фрагменты обратно и деконвертирую их из base64 в формат файла.

Есть ли лучший способ сделать это? Есть ли библиотека, которая обрабатывает все это вместо того, чтобы писать это с нуля? Я не уверен, что маршрут base64 - лучший способ сделать это.

Ответы [ 2 ]

0 голосов
/ 03 мая 2018

Нет необходимости читать содержимое в оперативную память с помощью FileReader использование base64 только увеличит размер того, что вам нужно загрузить

Используйте 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, chunkSize + 1)
  const fd = new FormData
  fd.append('data', chunk, file.name);

  await fetch(url, {method: 'post', body: fd}).then(res => res.text())
}
0 голосов
/ 01 мая 2018

Вы можете избежать необходимости кодировать base64, используя FileReader, а затем отправлять в двоичном виде:

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"/>
...