问题描述
为什么不推荐使用 readAsBinaryString()?来自 W3C
Why is readAsBinaryString() deprecated? From W3C
readAsArrayBuffer() 优于 readAsBinaryString(),后者是为了向后兼容而提供的.
readAsBinaryString 返回一个与其他方法完全不同的东西,那么一个方法怎么能替代另一个呢?
readAsBinaryString returns a completely different thing than the other method, so how could one be the replacement for the other?
在我的特定情况下,我有一个需要转换为 base64 的 Blob,有很多方法,但大多数方法都没有内存效率.在我的测试中,从 readAsBinaryString' 结果调用 window.btoa() 效果最好.如果我不能再使用它(或者现在可以说应该"),那么我必须使用迭代和字符串连接将数组转换为字符串,这根本不是内存效率!
In my specific case I have a Blob that I need to convert to base64, there are many ways, but most of them not memory efficient. As of my tests calling window.btoa() from readAsBinaryString' result works best. If I cannot use this anymore (or for now lets say "should"), then I must convert the array to a string using iteration and strings concatenation which is not memory efficient at all!
所以经过几天的研究,我真的没有找到 readAsBinaryString 的替代方案,这就是问题的原因,或者您是否看到了也适用于 100MB blob 的替代方案?
So after researching for days I don't really find an alternative to readAsBinaryString, that's why the question, or do you see an alternative that also works with 100MB blobs?
推荐答案
历史是 readAsBinaryString
出现在 FileReader API 的早期规范中,在 ArrayBuffer 接口存在.
The history is that readAsBinaryString
was present in an early specification of the FileReader API, before the ArrayBuffer interface exist.
当 ArrayBuffer 接口出现时,readAsBinaryString
已被弃用,因为它的所有用例都可以使用新接口以更好的方式完成.
实际上,readAsBinaryString
只是将二进制数据转换为 DOMString (UTF-16).之后你无能为力.此外,将其存储为 UTF-16 字符串意味着它在内存中占用的空间远大于原始数据大小.再加上字符串是不可变的,我想你可以看到它的工作效率有多低.
最后,如果你真的需要这个字符串,你实际上可以从一个 ArrayBuffer 做同样的事情,你只需要在这个 ArrayBuffer 的 Uint8 视图上调用 String.fromCharCode
.
When the ArrayBuffer interface appeared, readAsBinaryString
has been deprecated because all its use cases could be done in a better way using that new interface.
Indeed, readAsBinaryString
only converts the binary data into a DOMString (UTF-16). There is not much you can do from it afterward. Also, storing it as an UTF-16 string implies that it takes far more space in memory than the original data size. Add to this that strings are immutable, I guess you can see how inefficient it is to work from this.
And finally, if you really need to have this string, you can actually do the same from an ArrayBuffer, you just need to call String.fromCharCode
over an Uint8 view of this 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);
});
现在,这个方法虽然仍然非常无用,但已经重新添加到规范中,因为一些网站确实开始使用它.
Now, this method, while still very useless, has been re-added to the specs, because some websites did start using it.
为了更多地帮助 OP,因为他们实际上试图做的是获得他们 Blob 的 base64 版本,所以甚至不要使用 readAsArrayBuffer()
, readAsDataURL()
正是你所需要的:
And to help OP a bit more, since what they were trying to do was actually to get a base64 version of their Blob, then don't even use readAsArrayBuffer()
, readAsDataURL()
is what you need:
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);
这篇关于为什么不推荐使用 readAsBinaryString()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!