为什么不建议使用readAsBinaryString()

时间:2019-04-24 18:52:29

标签: javascript w3c

为什么不赞成使用readAsBinaryString()?来自W3C

  

使用readAsArrayBuffer()优于readAsBinaryString(),后者是为了向后兼容而提供的。

readAsBinaryString返回的结果与另一个方法完全不同,那么如何替代另一个方法?

在我的特定情况下,我有一个Blob,我需要将其转换为base64,有很多方法,但是其中大多数都不高效。在我的测试中,从readAsBinaryString的结果调用window.btoa()效果最佳。如果我不能再使用它了(或者现在让我们说“应该”),那么我必须使用迭代和字符串连接将数组转换为字符串,这根本就没有存储效率!

因此,在研究了几天之后,我真的没有找到readAsBinaryString的替代方法,这就是为什么要问这个问题,或者您是否看到一种也适用于100MB Blob的替代方法?

1 个答案:

答案 0 :(得分:0)

历史记录是readAsBinaryStringArrayBuffer接口存在之前出现在FileReader API的早期规范中。

出现ArrayBuffer接口时,readAsBinaryString已过时,因为使用该新接口可以更好地完成其所有用例。
实际上,readAsBinaryString仅将二进制数据转换为DOMString(UTF-16)。此后您无能为力。另外,将其存储为UTF-16字符串意味着它在内存中的空间比原始数据大小要多得多。此外,字符串是不可变的,我想您会发现使用此字符串效率很低。
最后,如果确实需要此字符串,则实际上可以从ArrayBuffer进行此操作,只需要在此ArrayBuffer的Uint8视图上调用String.fromCharCode

// 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,因为他们实际上想获得其Blob的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);