Почему readAsBinaryString () устарела - PullRequest
0 голосов
/ 24 апреля 2019

Почему readAsBinaryString () устарела? От W3C

Использование readAsArrayBuffer () предпочтительнее, чем readAsBinaryString (), что предусмотрено для обратной совместимости.

readAsBinaryString возвращает совершенно другую вещь, чем другой метод, так как один может заменить другой?

В моем конкретном случае у меня есть Blob, который мне нужно преобразовать в base64, есть много способов, но большинство из них неэффективно используют память. Что касается моих тестов, то вызов метода window.btoa () из readAsBinaryString 'работает лучше всего. Если я больше не могу использовать это (или пока давайте скажем «должен»), то я должен преобразовать массив в строку, используя итерацию и конкатенацию строк, что неэффективно для памяти вообще!

Так что после нескольких дней исследований я не нашел альтернативы readAsBinaryString, поэтому возникает вопрос, или вы видите альтернативу, которая также работает с каплями размером 100 МБ?

1 Ответ

1 голос
/ 22 мая 2019

История состоит в том, что readAsBinaryString присутствовал в более ранней спецификации API FileReader до появления интерфейса ArrayBuffer .

Когда появился интерфейс ArrayBuffer, readAsBinaryString устарел, поскольку все его варианты использования могли бы быть выполнены лучше с использованием этого нового интерфейса.
Действительно, readAsBinaryString только преобразует двоичные данные в строку DOMString (UTF-16). После этого мало что можно сделать из этого. Кроме того, хранение его в виде строки UTF-16 подразумевает, что он занимает гораздо больше места в памяти, чем исходный размер данных. Добавьте к этому, что строки неизменны, я думаю, вы можете видеть, насколько неэффективно работать с этим.
И, наконец, если вам действительно нужна эта строка, вы можете сделать то же самое из ArrayBuffer, вам просто нужно вызвать String.fromCharCode через Uint8-представление этого ArrayBuffer.

// generate some binary data
document.createElement('canvas').toBlob(blob => {
  const bin_reader = new FileReader();
  const arr_reader = new FileReader();
  let done = 0;
  bin_reader.onload = arr_reader.onload = e => {
    if(++done===2) {
      const arr_as_bin = [...new Uint8Array(arr_reader.result)]
        .map(v => String.fromCharCode(v)).join('');
      console.log('same results: ', arr_as_bin === bin_reader.result);
      console.log(arr_as_bin);
    }
  }
  bin_reader.readAsBinaryString(blob);
  arr_reader.readAsArrayBuffer(blob);
});

Теперь этот метод, хотя и очень бесполезный, был вновь добавлен в спецификации, потому что некоторые сайты начали его использовать.

И чтобы помочь OP немного больше, так как они пытались получить версию своего большого двоичного объекта для base64, тогда даже не используйте readAsArrayBuffer(), readAsDataURL() - это то, что вам нужно:

const blob = new Blob(['hello']);
const reader = new FileReader();
reader.onload = e => {
  const dataURL = reader.result;
  const base64 = dataURL.slice(dataURL.indexOf(',')+1);
  console.log(base64);
};
reader.readAsDataURL(blob);
...