提取具有不同类型数据的缓冲区

Extract a buffer having different types of data with it

缓冲区可以同时关联字符串和图像吗?如果有,如何分别提取。

一个例子是包含图像数据和文件名数据的缓冲区。

我以前和sharedArrayBuffers/arrayBuffers一起工作过。

如果您要存储图像像素数据,它将是一个 u32-int 数组,其中有 4 个 8 位段分别控制 rbga...是的:您可以在前面添加字符串数据,形式如下a 'header' 如果你对它进行编码并将其解码为 int 值......但我很难理解为什么这可能是可取的。因为处理只有 pixel-data 的原始像素数据更简单。 (我通常只是将它作为对象的 属性 粘贴,以及我想存储的任何其他数据)

数据缓冲区

类型化数组

您可以使用 ArrayBuffer to create a buffer to hold the data. You then create a view using a typed array. eg unsigned characters Uint8Array。类型可以是 8-16-32-64 位(un/signed 整数)、float - double(32 - 64 位浮点数)

一个缓冲区可以有多个视图。您可以像任何 JS 数组一样读取和写入视图。当您写入缓冲区时,这些值会自动转换为正确的类型,而当您从视图

中读取时,这些值会自动转换为 Number

例子

使用缓冲区和视图读取不同的数据类型

例如,假设您的文件数据具有 4 个字符 header,后跟一个 16 位无符号整数块长度,然后是 2 个有符号 16 位整数坐标,以及更多数据

const fileBuffer = ArrayBuffer(fileSizeInBytes);

// Create a view of the buffer so we can fill it with file data
const dataRaw = new Uint8Array(data);
// load the data into dataRaw 

// To get a string from the data we can create a util function
function readBufferString(buffer, start, length) {

    // create a view at the position of the string in the buffer
    const bytes = new Uint8Array(buffer, start, length);

    // read each byte converting to JS unicode string
    var str = "", idx = 0;
    while (idx < length) { str += String.fromCharCode(bytes[idx++]) }
    return str;
}

// get 4 char chunk header at start of buffer    
const header = readBufferString(fileBuffer, 0, 4);
if (header === "HEAD") {
    // Create views for 16 bit signed and unsigned integers
    const ints = new Int16Array(fileBuffer);
    const uints = new Uint16Array(fileBuffer);
    const length = uints[2]; // get the length as unsigned int16
    const x = ints[3]; // get the x coord as signed int16
    const y = ints[4]; // get the y coord as signed int16

一个DataView

以上示例是从单个缓冲区中提取不同类型数据的一种方法。然而,旧文件和一些数据源可能存在关于创建多字节类型(例如 32 整数)的字节顺序的问题。这叫做endianness

为了帮助使用正确的字节顺序并简化对缓冲区中所有不同数据类型的访问,您可以使用 DataView

数据视图可让您按类型和字节序从缓冲区中读取数据。例如从缓冲区

中读取一个无符号的 64 位整数
 // fileBuffer is a array buffer with the data
 // Create a view
 const dataView = new DataView(fileBuffer);
 
 // read the 64 bit uint starting at the first byte in the buffer
 // Note the returned value is a BigInt not a Number
 const bInt = dataView.getBigUint64(0);

 // If the int was in little endian order you would use
 const bInt = dataView.getBigUint64(0, true); // true for little E
 

备注

  • 缓冲区不是动态的。这意味着它们不能增长和收缩,并且您在创建缓冲区时必须知道缓冲区需要多大。

  • 缓冲区往往比 JavaScript 的标准数组慢一点,因为在读取或写入缓冲区时有很多类型强制转换

  • 缓冲区可以跨线程传输(零拷贝传输),这使它们成为在 WebWorker 之间分发大型数据结构的理想选择。还有一个 SharedArrayBuffer 可以让你在 JS 中创建真正的并行处理解决方案