Какой ArrayBufferView

Я извлекаю ArrayBuffer поверх XHR и хочу сохранить его в API FileSystem с помощью FileWriter. FileWriter ожидает, что Blob и конструктор Blob не возьмут ArrayBuffer, он возьмет ArrayBufferView.

Есть много вариантов ArrayBufferViews, откуда я могу узнать, что правильно использовать?

Ответы

Ответ 1

В MDN вы можете найти обзор всех доступных подклассов ArrayBufferView:

Type         | Size | Description                           | Equivalent C type
-------------+------+---------------------------------------+------------------
Int8Array    | 1    | 8-bit twos complement signed integer  | signed char
Uint8Array   | 1    | 8-bit unsigned integer                | unsigned char
Int16Array   | 2    | 16-bit twos complement signed integer | short
Uint16Array  | 2    | 16-bit unsigned integer               | unsigned short
Int32Array   | 4    | 32-bit twos complement signed integer | int
Uint32Array  | 4    | 32-bit unsigned integer               | unsigned int
Float32Array | 4    | 32-bit IEEE floating point number     | float
Float64Array | 8    | 64-bit IEEE floating point number     | double

В основном, это перечисляет, какие пространства памяти будут занимать каждый элемент массива, и если это простое число или номер FP. Я не уверен, на каких языках вы знакомы, но если он также охватывает Java, то это в основном тот же выбор, что и на byte[], short[], int[], float[] и double[] (Java всегда подписывается, поэтому часть не имеет значения).

Мы знаем, что двоичные данные, такие как изображения, обычно представляются в виде байтового массива. Короткий /int/long массив также может, но это пустая трата пространства памяти. Если вы сохранили бы изображение в 100 Кбайт (обратите внимание, что "B" означает байт, то есть 8 бит) в массиве int вместо байтового массива, тогда он будет занимать 400 Кбайт памяти, что является пустой тратой 300 КБ. Таким образом, самый маленький, Int8Array, будет уже достаточным в отношении пространства памяти. Если вы когда-нибудь захотите программно пройти через него — что очень маловероятно в этом случае; как беззнаковый массив, тогда вы можете выбрать Uint8Array вместо этого, где каждый элемент хранит значения 0 - 255 вместо значений -128 - 127.

Здесь пример copy'n'paste'n'runnable kickoff, который загружает файл изображения с сервера, сохраняет его во временном локальном хранилище и представляет его как <img> в теле (для jQuery требуется небольшое эта часть). В этом примере предполагается, что файл image.png находится в той же базовой папке, что и JS (или HTML, в случае, если JS является встроенным), файл загружен из:

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

Обратите внимание, что из состояния current это работает только в Chrome.