ArrayBuffer: примеры (JAVASCRIPT)
ArrayBuffer(byteLength: number): ArrayBufferБазовое описание ArrayBuffer
ArrayBuffer является низкоуровневым объектом, представляющим буфер с бинарными данными фиксированной длины в памяти. Он используется для работы с бинарными данными при взаимодействии с файлами, сетевыми запросами или графическими API.
Конструктор ArrayBuffer принимает один аргумент:
- length - размер буфера в байтах (целое число от 0 до 2^53-1).
Созданный буфер инициализируется нулями. ArrayBuffer не позволяет напрямую читать или записывать данные - для этого используются оболочки DataView или типизированные массивы (Uint8Array, Float32Array и другие).
Методы и свойства ArrayBuffer:
- byteLength - свойство, возвращающее размер буфера в байтах.
- slice(start, end) - создает новый буфер, копируя данные из исходного от позиции start до end (не включая).
- isView(view) - статический метод, проверяющий, является ли аргумент view оболочкой для буфера.
- transfer(oldBuffer, newByteLength) - статический метод для переноса буфера (ECMAScript 2024).
Примеры использования ArrayBuffer
Базовое создание буфера:
const buffer8 = new ArrayBuffer(8);
console.log(buffer8.byteLength);8
Использование типизированного массива для работы с буфером:
const buffer = new ArrayBuffer(16);
const int32View = new Int32Array(buffer);
for (let i = 0; i < int32View.length; i++) {
int32View[i] = i * 2;
}
console.log(int32View);Int32Array(4) [0, 2, 4, 6]
Копирование части буфера:
const original = new ArrayBuffer(16);
const view = new Uint8Array(original);
view[10] = 42;
const sliced = original.slice(8, 12);
console.log(new Uint8Array(sliced));Uint8Array(4) [0, 0, 42, 0]
Проверка оболочки буфера:
const buffer = new ArrayBuffer(8);
const view = new Float64Array(buffer);
console.log(ArrayBuffer.isView(view));
console.log(ArrayBuffer.isView([1, 2, 3]));true false
Похожие функции в JavaScript
SharedArrayBuffer позволяет разделять память между потоками Web Workers. Отличается возможностью совместного использования, но требует дополнительных мер синхронизации.
TypedArray (Uint8Array, Int16Array, Float32Array и другие) предоставляют интерфейс для работы с бинарными данными как с массивами определенного типа. Используются для доступа к данным ArrayBuffer.
DataView предлагает гибкий доступ к данным буфера с возможностью указания порядка байтов (endianness) и смещений в произвольных позициях.
Blob представляет неизменяемые сырые данные, часто используемые для работы с файлами. Может быть создан из ArrayBuffer.
Выбор зависит от задач: ArrayBuffer - для низкоуровневых операций, TypedArray - для типизированного доступа, DataView - для невыровненного доступа, SharedArrayBuffer - для многопоточности.
Типичные ошибки
Попытка прямого доступа к данным:
const buffer = new ArrayBuffer(4);
console.log(buffer[0]);undefined
Некорректный размер буфера:
try {
const buffer = new ArrayBuffer(-1);
} catch (e) {
console.log(e.toString());
}RangeError: Invalid array buffer length
Изменение размера существующего буфера:
const buffer = new ArrayBuffer(4);
buffer.byteLength = 8;// Ошибка: свойство byteLength доступно только для чтения
Ошибки при работе с несколькими представлениями:
const buffer = new ArrayBuffer(4);
const view1 = new Uint8Array(buffer);
const view2 = new Uint16Array(buffer);
view1[0] = 255;
console.log(view2[0]);65280 // Из-за разной интерпретации байтов
Изменения в последних версиях
В ECMAScript 2024 добавлен статический метод ArrayBuffer.transfer() для эффективного переноса или изменения размера буфера.
const buffer1 = new ArrayBuffer(8);
const view = new Uint8Array(buffer1);
view[0] = 42;
const buffer2 = ArrayBuffer.transfer(buffer1, 16);
console.log(buffer1.byteLength);
console.log(buffer2.byteLength);
console.log(new Uint8Array(buffer2)[0]);0 16 42
Метод transfer позволяет изменить размер буфера, перенося существующие данные. Исходный буфер становится detached (отсоединенным) с нулевой длиной.
Улучшена производительность операций с типизированными массивами в современных движках JavaScript.
Расширенные примеры использования
Чтение бинарного файла через FileReader:
// В контексте браузера
const fileInput = document.createElement('input');
fileInput.type = 'file';
fileInput.onchange = (e) => {
const file = e.target.files[0];
const reader = new FileReader();
reader.onload = (event) => {
const buffer = event.target.result;
console.log(`Размер файла: ${buffer.byteLength} байт`);
};
reader.readAsArrayBuffer(file);
};// Зависит от выбранного файла
Создание WAV-заголовка:
function createWavHeader(sampleRate, bitsPerSample, channels, duration) {
const buffer = new ArrayBuffer(44);
const view = new DataView(buffer);
// RIFF идентификатор
view.setUint8(0, 0x52); view.setUint8(1, 0x49);
view.setUint8(2, 0x46); view.setUint8(3, 0x46);
// Размер файла
const dataSize = sampleRate * duration * channels * bitsPerSample / 8;
view.setUint32(4, 36 + dataSize, true);
// WAVE идентификатор
view.setUint8(8, 0x57); view.setUint8(9, 0x41);
view.setUint8(10, 0x56); view.setUint8(11, 0x45);
return buffer;
}
const header = createWavHeader(44100, 16, 2, 5);
console.log(header.byteLength);44
Шифрование XOR:
function xorEncrypt(buffer, key) {
const result = new Uint8Array(buffer.byteLength);
const keyArray = new TextEncoder().encode(key);
for (let i = 0; i < buffer.byteLength; i++) {
result[i] = buffer[i] ^ keyArray[i % keyArray.length];
}
return result.buffer;
}
const data = new Uint8Array([65, 66, 67, 68]);
const encrypted = xorEncrypt(data.buffer, 'secret');
console.log(new Uint8Array(encrypted));Uint8Array(4) [18, 1, 14, 23]
Работа с WebSocket и бинарными данными:
// Клиентская часть
const socket = new WebSocket('ws://example.com');
socket.binaryType = 'arraybuffer';
socket.onmessage = (event) => {
if (event.data instanceof ArrayBuffer) {
const view = new Float32Array(event.data);
console.log('Получено чисел с плавающей точкой:', view.length);
}
};
// Отправка бинарных данных
const buffer = new ArrayBuffer(32);
const floatArray = new Float32Array(buffer);
floatArray[0] = 3.14159;
socket.send(buffer);// Зависит от серверной реализации
Альтернативы в других языках программирования
Python: модуль array и тип bytearray.
import array
arr = array.array('i', [1, 2, 3, 4])
print(arr.tobytes())b'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00'
PHP: ресурс stream и функции упаковки/распаковки.
$data = pack('i*', 1, 2, 3, 4);
echo bin2hex($data);01000000020000000300000004000000
C: указатели и динамическое выделение памяти.
#include
#include
int main() {
int *buffer = (int*)malloc(4 * sizeof(int));
for(int i = 0; i < 4; i++) buffer[i] = i + 1;
printf("%d", buffer[2]);
free(buffer);
return 0;
} 3
MySQL: тип данных BLOB для хранения бинарных данных.
Основные отличия: в JavaScript ArrayBuffer управляется сборщиком мусора, имеет строгую типизацию через оболочки и ограниченную арифметику указателей.