Правильный способ чтения файла с помощью FileReader () для создания строки хеша md5 из файлов изображений? - PullRequest
0 голосов
/ 07 июня 2019

В настоящее время я делаю это (см. Фрагмент ниже), чтобы получить md5 строку хэша для загружаемых файлов изображений (я использую хэш как fileNames):

ПРИМЕЧАНИЕ: Я использую пакет md5 для генерации хэша (он загружен во фрагмент).

В FileReader() есть 4 доступных метода для чтения файлов.Кажется, что все они дают хорошие результаты.

  • readAsText (файл)
  • readAsBinaryString (файл);
  • readAsArrayBuffer (файл);
  • readAsDataURL(файл);

Что я должен использовать в этом случае и почему?Можете ли вы также объяснить разницу между ними?

function onFileSelect(e) {
  const file = e.target.files[0];
  const reader1 = new FileReader();
  const reader2 = new FileReader();
  const reader3 = new FileReader();
  const reader4 = new FileReader();
  
  reader1.onload = (event) => {
    const fileContent = event.target.result;
    console.log('Hash from "readAsText()": ');
    console.log(md5(fileContent));
  }
  
  reader2.onload = (event) => {
    const fileContent = event.target.result;
    console.log('Hash from "readAsBinaryString()": ');
    console.log(md5(fileContent));
  }
  
  reader3.onload = (event) => {
    const fileContent = event.target.result;
    console.log('Hash from "readAsArrayBuffer()": ');
    console.log(md5(fileContent));
  }
  
  reader4.onload = (event) => {
    const fileContent = event.target.result;
    console.log('Hash from "readAsDataURL()": ');
    console.log(md5(fileContent));
  }
  
  reader1.readAsText(file);
  reader2.readAsBinaryString(file);
  reader3.readAsArrayBuffer(file);
  reader4.readAsDataURL(file);
  
}
.myDiv {
  margin-bottom: 10px;
}
<script src="https://cdn.jsdelivr.net/npm/js-md5@0.7.3/src/md5.min.js"></script>
<div class="myDiv">Pick an image file to see the 4 hash results on console.log()</div>
<input type='file' onChange="onFileSelect(event)" accept='.jpg,.jpeg,.png,.gif' />

1 Ответ

1 голос
/ 10 июня 2019

Использование readAsArrayBuffer.

readAsBinaryString() и readAsDataURL() заставят ваш компьютер выполнять намного больше работы, чем необходимо:

  1. читать BLOB-объекты как двоичный поток
  2. преобразовать в строку UTF-16 / base64 (помните, что строки не являются изменяемыми в js, любая операция, которую вы над ней выполняете, фактически создает копию в памяти)
  3. [перейти к вашей библиотеке]
  4. преобразовать в двоичную строку
  5. обработка данных

Кроме того, похоже, что ваша библиотека не обрабатывает URL-адреса данных и не работает со строками UTF-16.

readAsText() по умолчанию попытается интерпретировать ваши двоичные данные как текстовую последовательность UTF-8, что довольно плохо для двоичных данных, таких как растровое изображение:

// generate some binary data
document.createElement('canvas').toBlob(blob => {
  const utf8_reader = new FileReader();
  const bin_reader = new FileReader();
  let done = 0;
  utf8_reader.onload = bin_reader.onload = e => {
    if(++done===2) {
      console.log('same results: ', bin_reader.result === utf8_reader.result);
      console.log("utf8\n", utf8_reader.result);
      console.log("utf16\n", bin_reader.result);
    }
  }
  utf8_reader.readAsText(blob);
  bin_reader.readAsBinaryString(blob);
});

readAsArrayBuffer, с другой стороны, будет просто распределять двоичные данные как есть в памяти. Простой ввод / вывод, без обработки.
Чтобы манипулировать этими данными, мы можем использовать представления TypedArrays для этих двоичных данных, которые, будучи только представлениями, также не будут создавать никаких накладных расходов.

И если вы посмотрите на библиотеку, которую вы используете , они все равно передадут ваш ввод в такой массив Uint8Array для дальнейшей обработки. Однако имейте в виду, что они, очевидно, нуждаются в том, чтобы вы передавали представление ArintBuffer в Uint8Array вместо обнаженного ArrayBuffer напрямую.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...