往返Blob到数组将数组值增加48

时间:2019-02-13 08:18:07

标签: javascript arrays string data-conversion

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

3 个答案:

答案 0 :(得分:3)

问题在于Blob的构造函数将数组中的数字转换为字符串。根据{{​​3}}文档Blob的构造函数,使用ArrayArrayBufferArrayBufferView,{{1}的 array },Blob对象或任何此类对象的混合作为第一参数。所有这些都将被串联并放入DOMString中。因此,您传递的数组中的每个元素都是单独处理的。它们被转换为字符串(请参见MDN表,“ 1”的代码为49,依此类推),然后放入Blob中。
请注意,这四个表达式的结果相同:

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(arrayToBlob([1,2,3]), console.log) blobToArray(arrayToBlob(['1','2','3']), console.log) blobToArray(arrayToBlob([123]), console.log) blobToArray(arrayToBlob(['123']), console.log)

Blob

支付attansion,我如何将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)传递给Uint8ArrayBlob。我将其放置在数组中,因此return new Blob([data]);作为第一个参数不会被视为对象本身的数组。
总结:您并不是真正的往返,而是从一种类型的数组开始并将其转换为另一种类型的数组。如果从一开始就使用propper数组,那么一切都会起作用。

答案 1 :(得分:0)

一个Blob的行为就像一个文件,我在文档中没有任何地方看到使用构造函数和数组,元素被视为文本(分隔字符),但是看起来确实如此,所以转换是是在Blob构造上进行的(请注意,您没有为Blob提供任何mime类型,但在我的测试中并未影响这些功能的结果)。您可以在我的示例中使用第二个函数来验证它是否确实有效,将其作为文本读取会产生字符串"123"

为了能够看到这一点,我经历了一些quite extended and interesting article,而this SO answer最初建议将ArrayBuffer转换为Uint8Array

似乎还可以更轻松地存储和检索值,可以使用DataView,还没有尝试过,但是您可以找到MDN reference here

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)

答案 2 :(得分:0)

尝试这种方式

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();

例如,您可以使用Uint8Array代替Int32Array在数组中使用大于255的负数。我还使用async / await方法来使代码看起来更同步且嵌套更少(如您所见,未使用任何显式回调)。