Which ArrayBufferView
Asked Answered
R

1

15

I'm retrieving an ArrayBuffer over XHR and want to save it to the FileSystem API using a FileWriter. The FileWriter expects a Blob and the Blob constructor won't take an ArrayBuffer, it takes an ArrayBufferView.

There are many ArrayBufferViews to choose from, how do I know which is the correct to use?

Roybal answered 13/1, 2013 at 22:41 Comment(0)
C
17

At MDN, you can find an overview of all available ArrayBufferView subclasses:

Type Bytes Description Equivalent C type
Int8Array 1 8-bit twos complement signed integer int8_t
Uint8Array 1 8-bit unsigned integer uint8_t
Uint8ClampedArray 1 8-bit unsigned integer (clamped) uint8_t
Int16Array 2 16-bit twos complement signed integer int16_t
Uint16Array 2 16-bit unsigned integer uint16_t
Int32Array 4 32-bit twos complement signed integer int32_t
Uint32Array 4 32-bit unsigned integer uint32_t
Float32Array 4 32-bit IEEE floating point number float
Float64Array 8 64-bit IEEE floating point number double
BigInt64Array 8 64-bit two's complement signed integer int64_t
BigUint64Array 8 64-bit unsigned integer uint64_t

Basically, this lists what memory spaces each item of the array would occupy and if it's a plain number or a FP number. I'm not sure what languages you're familiar with, but if it also covers Java, then it is basically the same choice as you'd make on byte[], short[], int[], float[] and double[] (Java is always signed, so that part doesn't matter).

We know, binary data like images is usually represented as a byte array. A short/int/long array can also, but this is a waste of memory space. If you would store a 100KB image (note that "B" stands for byte, which is 8 bits) in an int array instead of a byte array, then it would occupy 400KB of memory, which is a waste of 300KB. So the smallest one, Int8Array, would already suffice with regard to memory space. If you'd ever like to programmatically traverse it — which is very unlikely in this case — as an unsigned array, then you may opt for the Uint8Array instead where each item holds values 0 to 255 instead of values -128 to 127.

Here's a copy'n'paste'n'runnable kickoff example which downloads an image file from the server, saves it to the temporary local storage space and presents it as an <img> in the body (little jQuery is required for that part). This example assumes that the image.png file is located in the same base folder as the JS (or HTML, in case JS is inlined) file is been downloaded from:

window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
window.requestFileSystem(window.TEMPORARY, 1024*1024, startDownload, errorHandler);

var errorHandler = function(error) {
    console.log('FS error: ' + error);
}

var xhr = new XMLHttpRequest();
xhr.open('GET', 'image.png', true);
xhr.responseType = 'arraybuffer';

function startDownload(fileSystem) {
    xhr.onload = function(event) {
        var content = new Int8Array(this.response);
        fileSystem.root.getFile('/image.png', { 'create': true }, function(fileEntry) {
            fileEntry.createWriter(function(fileWriter) {
                fileWriter.onwriteend = function(event) {
                    $('body').append('<p>Image successfully downloaded:</p>')
                             .append('<p><img src="' + fileEntry.toURL() + '"/></p>');
                };

                var blob = new Blob([content], { type: 'image/png' });
                fileWriter.write(blob);
            }, errorHandler);
        });
    }

    xhr.send();
}

Note, as of the current state, this works in Chrome, Edge and Opera only and not (yet?) in Safari nor Firefox.

Canarese answered 18/1, 2013 at 2:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.