Search code examples
javascriptblobfilereaderarraybuffertyped-arrays

Reading ArrayBuffer from Blob has wrong data


I defined a simple Uint8Array with values [0,1,2,3]. Then I made a Blob object with this binary data, and read from fileReader with readAsArrayBuffer method. But when I got the values from blob, it contains [48, 49, 50, 51], not [0,1,2,3]!

This is the source code:

var bin = new Uint8Array(4);
bin[0] = 0;
bin[1] = 1;
bin[2] = 2;
bin[3] = 3;
console.log(bin);    // [0,1,2,3]

var blob = new Blob(bin);

var fileReader = new FileReader();
fileReader.onload = function() {
    var buffer = fileReader.result;
    var dv = new DataView(buffer);
    console.log(new Uint8Array(buffer));    // [49,50,51,52]

    var dv = new DataView(buffer);
    console.log([
        dv.getUint8(0),
        dv.getUint8(1),
        dv.getUint8(2),
        dv.getUint8(3)
    ]);    // it also prints [49,50,51,52]
    };
};

fileReader.readAsArrayBuffer(blob);

Why this is happening? I wrote 0,1,2,3 but every value were added 48 more. Is there a something that I missed?


Solution

  • The Blob constructor takes an array of arrays. Right now you're passing it a single Uint8Array which it tries to convert to text. (You can see the chars 49,50,51,51 translates to textual/ASCII representation of 1,2,3 and 4).

    To correct simply change this line to embed bin in an array - although the typed array is technically an array it will need a regular array to hold/reference the various data regardless of what the data is:

    var blob = new Blob([bin]);
    

    I would recommend using a mime-type as well but is not really needed in this case.

    var bin = new Uint8Array(4);
    bin[0] = 0;
    bin[1] = 1;
    bin[2] = 2;
    bin[3] = 3;
    console.log(bin);    // [0,1,2,3]
    
    var blob = new Blob([bin]);  // !! <- make sure this is passed an array
    
    var fileReader = new FileReader();
    fileReader.onload = function() {
        var buffer = fileReader.result;
        var dv = new DataView(buffer);
        console.log(new Uint8Array(buffer));
    
        var dv = new DataView(buffer);
        console.log([
            dv.getUint8(0),
            dv.getUint8(1),
            dv.getUint8(2),
            dv.getUint8(3)
        ]);
    };
    
    fileReader.readAsArrayBuffer(blob);