问题描述
我有两个函数用于在Blob
和字节数组之间进行转换:
function arrayToBlob(data) {
return new Blob(data);
}
function blobToArray(data, callback) {
let reader = new FileReader();
reader.addEventListener("loadend", function() {
callback(Array.from(new Uint8Array(reader.result)));
});
reader.readAsArrayBuffer(data);
}
( blobToArray
需要回调,因为它需要设置一个事件监听器。)
我希望这些函数彼此相反,但是当我运行时
blobToArray(arrayToBlob([1,2,3]), console.log)
我得到的结果不是[1, 2, 3]
,而是[49, 50, 51]
。
据推测,我正在做的是将数字转换为ASCII值,但我不知道哪个部分是负责任的。
1楼
问题是Blob
的构造函数将数组中的数字转换为字符串。
按照文档Blob
的构造需要和阵列 Array
或ArrayBuffer
, ArrayBufferView
, Blob
, DOMString
对象,或上述任何物体的混合,作为第一参数。
所有这些将被连接并放入Blob
。
因此,您传递的数组中的每个元素都由它自己处理。
它们被转换为字符串(参见表,'1'的代码是49,依此类推)并放入Blob中。
请注意,这4个表达式的结果是相同的:
function arrayToBlob(data) { return new Blob(data); } function blobToArray(data, callback) { let reader = new FileReader(); reader.addEventListener("loadend", function() { callback(Array.from(new Uint8Array(reader.result))); }); reader.readAsArrayBuffer(data); } blobToArray(arrayToBlob([1,2,3]), console.log) blobToArray(arrayToBlob(['1','2','3']), console.log) blobToArray(arrayToBlob([123]), console.log) blobToArray(arrayToBlob(['123']), console.log)
如果要获取二进制数组,则需要将propper二进制数组传递给Blob
:
function arrayToBlob(data) { return new Blob([data]); } function blobToArray(data, callback) { let reader = new FileReader(); reader.addEventListener("loadend", function() { callback(Array.from(new Uint8Array(reader.result))); }); reader.readAsArrayBuffer(data); } var arr = new Uint8Array(3); arr[0]=1; arr[1]=2; arr[2]=3; blobToArray(arrayToBlob(arr), console.log)
支持我如何将Uint8Array
传递给Blob
: return new Blob([data]);
。
我把它放在一个数组中,所以它不被视为Blob
作为第一个参数的对象数组本身。
总结:你没有真正进行往返,你开始使用一种类型的数组并将其转换为另一种类型的数组。
如果你从一开始就使用propper数组,那么每件事都有效。
2楼
Blob
行为就像一个文件,我在文档中没有看到使用带数组的构造函数,元素被作为文本(单独的字符)进行处理,但它似乎是这样,所以转换是在Blob
构造中进行的(注意你没有为Blob提供任何mime类型,但在我的测试中没有影响这些函数的结果)。
您可以使用我的示例中的第二个函数进行验证,将其作为文本结果读取字符串"123"
。
为了能够看到这一点,我经历了一些 ,并且ArrayBuffer
到Uint8Array
之间的转换Uint8Array
是由提出的。
另外似乎更容易存储和检索值,可以使用DataView
,没试过但你可以找到
function arrayToBlob(data) { return new Blob(data); } function blobToArray(data, callback) { let reader = new FileReader(); reader.addEventListener("loadend", function() { callback( Array.from((new Uint8Array(reader.result)).map(function(a){ return String.fromCharCode(a); })) ); }); reader.readAsArrayBuffer(data); } function blobToArrayAsText(data, callback) { let reader = new FileReader(); reader.addEventListener("loadend", function() { callback( Array.from(reader.result) ); //result is "123" here }); reader.readAsText(data); } blobToArray(arrayToBlob([1,2,3]), console.log) blobToArrayAsText(arrayToBlob([1,2,3]), console.log)
3楼
试试这种方式
function ArrToBlob(arr) { return new Blob([new Uint8Array(arr)]); } async function BlobToArr(blob) { return [...new Uint8Array(await new Response(blob).arrayBuffer())]; } async function start() { let a=[1,2,3]; let b= ArrToBlob(a); let c = await BlobToArr(b); let j=JSON.stringify; console.log('input :',j(a)); console.log('blob :',j(b)); console.log('output:',j(c)); } start();
您可以使用例如Int32Array
在数组中使用负数和大于255的数字,而不是使用Uint8Array
。
我还使用async / await方法使代码看起来更加同步并且嵌套更少(因为你可以看到没有使用explicte回调)。