Как преобразовать Int32Array в Uint8Array без копирования

#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.