#node.js
#node.js
Вопрос:
У меня есть объект типа Int32Array
длины 1
, и я хотел бы преобразовать его в объект типа Uint8Array
длины 4
, предпочтительно без копирования содержимого памяти. Как я могу это сделать?
[ОБНОВИТЬ]
Чтобы лучше объяснить мою проблему, рассмотрим следующий код:
const view = new DataView(int32array.buffer);
const uni8array = new Uint8Array(int32array.length * 4);
for (let i=0; i<int32array.length; i ) {
uni8array[i*4 0] = view.getUint8(i*4 0);
uni8array[i*4 1] = view.getUint8(i*4 1);
uni8array[i*4 2] = view.getUint8(i*4 2);
uni8array[i*4 3] = view.getUint8(i*4 3);
}
Этот код делает именно то, что я хочу сделать, но он копирует исходный массив в новый. Я надеялся, что есть способ сделать то же самое без копирования памяти.
Комментарии:
1. Возможно, создайте DataView , который предоставляет другой интерфейс (включая возможность извлекать любое значение uint8) для вашего объекта ArrayBuffer.
2. @jfriend00 Спасибо. Я уже рассматривал это. Просто это
DataView
дает мне возможность считывать данные только по одному элементу за раз. Я надеялся найти способ привести весь массив без копирования.3. Что вы на самом деле пытаетесь тогда сделать? Пожалуйста, опишите проблему в целом. Почему вы начинаете с Int32Array в первую очередь и почему вам нужны те же данные в Uint8Array без копирования. Прямо сейчас ваш вопрос представляет собой проблему XY, в которой вы запрашиваете конкретное решение без описания реальной проблемы здесь, и, таким образом, мы не можем увидеть проблему в целом и не можем предложить вам то, о чем вы даже не подумали.
4. @jfriend00 Я обновил вопрос. Проблема, которую я пытаюсь решить, заключается в том, что у меня есть две библиотеки. Один выводит,
Int32Array
а другой ожидаетUint8Array
. Данные те же, проблема только в их типе.5. Я не вижу никакого способа сделать то, что вы пытаетесь сделать, с помощью простого Javascript. Если это модуль, закодированный на Javascript, который создает Uint32Array, возможно, вы могли бы отредактировать исходный модуль, чтобы создать и заполнить Uint8Array в первую очередь.
Ответ №1:
Я не вижу никакого способа сделать то, что вы пытаетесь сделать, с помощью простого Javascript.
Если исходный модуль является модулем, закодированным на Javascript, который создает Uint32Array
, возможно, вы могли бы отредактировать исходный модуль, чтобы в первую очередь создать и заполнить Uint8Array
и избежать проблемы преобразования.
Другая возможность заключается в том, что вы могли бы создать свою собственную оболочку для Uint32Array
, которая предоставляет вам доступ как виртуальный Uint8Array
, где вы скрываете сложность динамического получения соответствующего значения Uint8 из Uint32Array (без необходимости его копирования), а затем просто закодировать доступ к нему, используя ваши методы оболочки.
Комментарии:
1. @mehran — Я добавил заметку о том, как вы могли бы создать оболочку вокруг Uint32Array, которая предоставляет вам интерфейс, подобный Uint8Array.
Ответ №2:
(лучше поздно, чем никогда?)
Создайте Uint8Array непосредственно из ArrayBuffer, возвращенного из .buffer
. Или если с помощью Node.js , тогда Buffer.from(...)
. Найдите «совместно использует ту же выделенную память» в https://nodejs.org/api/buffer.html#buffers-and-typedarrays .
const u32s = Uint32Array.of (3, 8);
const u8s_plainJS = new Uint8Array(u32s.buffer);
//const u8s_NodeJS = Buffer.from(u32s.buffer);
console.log(u8s_plainJS); // [ 3, 0, 0, 0, 8, 0, 0, 0 ] on my little-endian platform
Как упоминали другие, если вам нужно беспокоиться о последовательности в конце, вам может потребоваться использовать DataView.