当前位置: 代码迷 >> JavaScript >> Round-tripping Blob to Array为数组值增加了48
  详细解决方案

Round-tripping Blob to Array为数组值增加了48

热度:79   发布时间:2023-06-12 14:05:23.0

我有两个函数用于在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值,但我不知道哪个部分是负责任的。

问题是Blob的构造函数将数组中的数字转换为字符串。 按照文档Blob的构造需要和阵列 ArrayArrayBufferArrayBufferViewBlobDOMString对象,或上述任何物体的混合,作为第一参数。 所有这些将被连接并放入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传递给Blobreturn new Blob([data]); 我把它放在一个数组中,所以它不被视为Blob作为第一个参数的对象数组本身。
总结:你没有真正进行往返,你开始使用一种类型的数组并将其转换为另一种类型的数组。 如果你从一开始就使用propper数组,那么每件事都有效。

Blob行为就像一个文件,我在文档中没有看到使用带数组的构造函数,元素被作为文本(单独的字符)进行处理,但它似乎是这样,所以转换是在Blob构造中进行的(注意你没有为Blob提供任何mime类型,但在我的测试中没有影响这些函数的结果)。 您可以使用我的示例中的第二个函数进行验证,将其作为文本结果读取字符串"123"

为了能够看到这一点,我经历了一些 ,并且ArrayBufferUint8Array之间的转换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) 

试试这种方式

 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回调)。

  相关解决方案