Pull to refresh
0
Microsoft
Microsoft — мировой лидер в области ПО и ИТ-услуг

Работа с бинарными данными с использованием типизированных массивов

Reading time5 min
Views28K
Original author: Luke Hoban
Вместе с HTML5 в веб-разработку приходят новые API, расширяющие UX, привнося новые мультимедийные возможности и возможности взаимодействия в реальном времени. Зачастую этот функционал завязан на использование бинарных форматов файлов вроде MP3-аудио, PNG-изображений
или MP4-видео. Использование бинарных файлов крайне важно в данном контексте, так как позволяет уменьшить требования к ширине канала, добиться необходимой производительности и вместе с этим оставаться совместимым с имеющимися технологиями. Еще недавно у веб-разработчиков не было прямого доступа к содержимому этих бинарных файлов или любых других бинарных форматов файлов.

В этой статье мы рассмотрим, как веб-разработчики могут снять этот барьер, используя
Typed Arrays API для JavaScript, и использование нового API в демонстрационном примере Binary File Inspector на IE Test Drive.

Типизированные массивы, доступные в IE10 Platform Preview 4, позволяют веб-приложениями работать с широким спектром бинарных файлов и напрямую работать с двоичным контентом поддерживаемых браузером файлов. Поддержка Typed Arrays была добавлена по всему IE10: в JavaScript, в XMLHttpRequest, в File API и в Stream API.

Binary File Inspector


Пример Binary File Inspector показывает некоторые из новых возможностей, работающих при сочетании этих функций. Вы можете посмотреть ID3-заголовки музыкальных файлов, понять, как выглядит сырые данные в видео-файлах, а также посмотреть файлы других форматов вроде PCX-изображений, которые могут поддерживаться
браузером с помощью JavaScript и Canvas.

Binary File Inspector

На примере выше .mp4-видео рендерится с помощью <video>-элемента слева, а бинарное содержимое файла отображается справа в шестнадцатеричном (HEX) формате и в виде соответствующих ASCII-символов. В этом примере вы можете увидеть несколько характерных для MPEG-файлов элементов вроде «ftyp» для «mp4».

Typed Arrays и ArrayBuffers


Типизированные массивы предоставляют возможность взгялнуть на сырое бинарное содержимое через то или иное типизированное представление. Например, если мы хотим смотреть на бинарный поток данных как байтовый массив, мы можем использовать Uint8Array (Uint8 описывает 8-битовое беззнаковое целое значение, обычно называемое байтом). Если мы хотим считывать сырые данные как массив чисел с плавающей точкой, мы можем использовать Float32Array (Float32 описывает 32-битное число с плавающей точкой в соответствии со стандартом IEE754). Поддерживаются следующие типы:
Тип массива Размер элемента и описание
Int8Array 8-bit signed integer
Uint8Array 8-bit unsigned integer
Int16Array 16-bit signed integer
Uint16Array 16-bit unsigned integer
Int32Array 32-bit signed integer
Uint32Array 32-bit unsigned integer
Float32Array 32-bit IEEE754 floating point number
Float64Array 64-bit IEEE754 floating point number

Каждый тип массива — это представление для ArrayBuffer. ArrayBuffer — это ссылка на поток бинарных данных, но он не представляет никакого прямого способа для взаимодействия с данными. Создание TypedArray-представления для ArrayBuffer предоставляет доступ к чтению и записи бинарного содержимого.


Пример ниже создает новый ArrayBuffer с нуля и интерпретирует его содержимое различными способами:
// Create an 8 byte buffer
var buffer = new ArrayBuffer(8);
 
// View as an array of Uint8s and put 0x05 in each byte
var uint8s = new Uint8Array(buffer);
for (var i = 0; i < 8; i++) {
    uint8s[i] = 5; // fill each byte with 0x05
}
 
// Inspect the resulting array
uint8s[0] === 5; // true - each byte has value 5
uint8s.byteLength === 8; // true - there are 8 Uint8s
 
// View the same buffer as an array of Uint32s 
var uint32s = new Uint32Array(buffer);
 
// The same raw bytes are now interpreted differently
uint32s[0] === 84215045 // true - 0x05050505 == 84215045


Таким образом, типизированные массивы могут быть использованы для таких задач как создание значений с плавающей точкой из их по-байтовых компонент построения структур данных, требующих специфичной компоновки данных, исходя из соображений эффективности и совместимости.

Typed Arrays для чтения бинарных файлов


Важный новый сценарий, ставший возможным благодаря типизированным массивам, это чтение и отображение содержимого бинарных файлов, неподдерживаемых напрямую браузером. Вместе с различными типизированными массивами, описанными выше, Typed Arrays также предоставляет специальный объект DataView, который можно использовать для чтения и записи содержимого ArrayBuffer в неструктурированном виде. Это хорошо подходит для чтения новых форматов файлов, которые обычно построены поверх смешанных типов данных.

Binary File Inspector использует DataView для чтения PCX-файлов и их рендеринга с использованием <canvas>-элемента. Ниже приведена упрощенная версия того, что делается в демонстрационном примере для чтения заголовка файла, включая получения информации о ширине и высоте, DPI и глубине цвета (bits-per-pixel).

var buffer = getPCXFileContents();
 var reader = new DataView(buffer);
 
// Read the header of the PCX file 
var header = {};
 
// The first section is single bytes 
header.manufacturer = reader.getUint8(0); 
header.version = reader.getUint8(1); 
header.encoding = reader.getUint8(2); 
header.bitsPerPixel = reader.getUint8(3); 
 
// The next section is Int16 values, each in little-endian 
header.xmin = reader.getInt16(4, true); 
header.ymin = reader.getInt16(6, true); 
header.xmax = reader.getInt16(8, true); 
header.ymax = reader.getInt16(10, true); 
header.hdpi = reader.getInt16(12, true); 
header.vdpi = reader.getInt16(14, true);


Код, аналогичный приведенному выше, может быть использован для добавления поддержки рендеринга в браузере широкого спектра новых типов файлов, включая собственные форматы изображений, дополнительные форматы видео-файлов и форматы данных, специфичных для той или иной области.

Получение двоичных данных через XHR и File API


Прежде, чем мы сможем использовать Typed Arrays API для работы с содержимым файлов, нам необходимо использовать соответствующие API браузера для получения доступа к сырым данным. Для доятупа к файлам с сервера XMLHttpRequest API был расширен с добавлением поддержки различных типов ответа (responseType). Так ответ в виде «arraybuffer» представляет содержимое ресурса, запрошенного с сервера, в виде ArrayBuffer-объекта для JavaScript. Также поддерживаются «blob», «text» и «document» ответы.


function getServerFileToArrayBufffer(url, successCallback) {
    // Create an XHR object
    var xhr = new XMLHttpRequest();
 
    xhr.onreadystatechange = function () {
        if (xhr.readyState == xhr.DONE) {
            if (xhr.status == 200 && xhr.response) {
                // The 'response' property returns an ArrayBuffer
                successCallback(xhr.response);
            } else {
                alert("Failed to download:" + xhr.status + " " + xhr.statusText);
            }
        }
    }
    // Open the request for the provided url
    xhr.open("GET", url, true);
    
    // Set the responseType to 'arraybuffer' for ArrayBuffer response
    xhr.responseType = "arraybuffer";
 
    xhr.send();
}

Во многих случаях файлы могут выбираться пользователем, например, в виде приложения к письму в веб-клиенте для почты. File API предоставляет веб-разработчикам возможность чтения содержимого файлов, указанных через <input>-элемент, при перетаскивании (drag and drop) или из другого источника (Blob, File). Для чтения содержимого файла в ArrayBuffer используется объект FileReader и, подобно XHR-объекту, он используется асинхронно, чтобы убедиться, что чтение с диска не блокирует пользовательский интерфейс.

function readFileToArrayBuffer(file, successCallback) {
    // Create a FileReader 
    var reader = new FileReader();
 
    // Register for 'load' and 'error' events
    reader.onload = function () {
        // The 'result' property returns an ArrayBuffer for readAsArrayBuffer 
        var buffer = reader.result;
        successCallback(buffer);
    }
 
    reader.onerror = function (evt) {
        // The error code indicates the reason for failure
        if (evt.target.error.code == evt.target.error.NOT_READABLE_ERR) {
            alert("Failed to read file: " + file.name);
        }
    }
 
    // Begin a read of the file contents into an ArrayBuffer
    reader.readAsArrayBuffer(file);
}


Заключение


Бинарные данных активно используются веб-браузерами. С добавлением поддержки Typed Arrays, XHR2 и File API в IE10 веб-приложения теперь могут тоже напрямую работать с бинарными данными, манипулировать данными на по-байтовом уровне, отображать дополнительные бинырные форматы данных и извлекать дополнительные данные из существующих медиа-форматов. Попробуйте пример Binary File Inspector на IE Test Drive, и реализацию Typed Arrays в IE10.
Tags:
Hubs:
+12
Comments3

Articles

Information

Website
www.microsoft.com
Registered
Founded
Employees
Unknown
Location
США