HarmonyOS鸿蒙Next应用开发arrayBuffer和Uint8Array互相转化

HarmonyOS鸿蒙Next应用开发arrayBuffer和Uint8Array互相转化

鸿蒙应用开发arrayBuffer和Uint8Array互相转化

1. ArrayBuffer 和 Uint8Array 分别是什么

ArrayBuffer

ArrayBuffer 是一个通用的、固定长度的原始二进制数据缓冲区。它本身并不能直接操作数据,而是需要通过“视图”对象来读写缓冲区中的内容。

特点:

  • 表示一段内存区域
  • 不能直接读写
  • 需要通过类型化数组或DataView对象来操作
  • 创建时需要指定字节长度

创建示例:

// 创建一个8字节的ArrayBuffer
const buffer = new ArrayBuffer(8);

Uint8Array

Uint8Array 是类型化数组的一种,表示一个8位无符号整型数组。它提供了一种访问ArrayBuffer中数据的机制。

特点:

  • 每个元素是0-255之间的整数
  • 可以直接读写数组元素
  • 是ArrayBuffer的一种视图
  • 常用于处理二进制数据

创建示例:

// 创建一个长度为8的Uint8Array
const uint8Array = new Uint8Array(8);

// 从ArrayBuffer创建Uint8Array
const buffer = new ArrayBuffer(8);
const uint8ArrayFromBuffer = new Uint8Array(buffer);

2. 互相转化源码

ArrayBuffer 转 Uint8Array

/**
 * ArrayBuffer 转 Uint8Array
 * @param {ArrayBuffer} arrayBuffer - 要转换的ArrayBuffer
 * @returns {Uint8Array} 转换后的Uint8Array
 */
function arrayBufferToUint8Array(arrayBuffer) {
    // 方法1:直接使用Uint8Array构造函数
    return new Uint8Array(arrayBuffer);
    
    // 方法2:使用slice确保数据独立性
    // return new Uint8Array(arrayBuffer.slice(0));
}

// 使用示例
const buffer = new ArrayBuffer(16);
const uint8Array = arrayBufferToUint8Array(buffer);
console.log(uint8Array); // Uint8Array(16) [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

Uint8Array 转 ArrayBuffer

/**
 * Uint8Array 转 ArrayBuffer
 * @param {Uint8Array} uint8Array - 要转换的Uint8Array
 * @returns {ArrayBuffer} 转换后的ArrayBuffer
 */
function uint8ArrayToArrayBuffer(uint8Array) {
    // 方法1:直接访问buffer属性(共享内存)
    return uint8Array.buffer;
    
    // 方法2:创建新的ArrayBuffer(独立内存)
    // const buffer = new ArrayBuffer(uint8Array.length);
    // const newUint8Array = new Uint8Array(buffer);
    // newUint8Array.set(uint8Array);
    // return buffer;
}

// 使用示例
const uint8Array = new Uint8Array([1, 2, 3, 4, 5]);
const buffer = uint8ArrayToArrayBuffer(uint8Array);
console.log(buffer.byteLength); // 5

完整转换示例

// 创建ArrayBuffer并填充数据
const originalBuffer = new ArrayBuffer(4);
const view = new DataView(originalBuffer);
view.setUint8(0, 10);
view.setUint8(1, 20);
view.setUint8(2, 30);
view.setUint8(3, 40);

// ArrayBuffer 转 Uint8Array
const uint8Array = new Uint8Array(originalBuffer);
console.log('Uint8Array:', Array.from(uint8Array)); // [10, 20, 30, 40]

// 修改Uint8Array
uint8Array[0] = 100;

// Uint8Array 转 ArrayBuffer
const convertedBuffer = uint8Array.buffer;
const newView = new DataView(convertedBuffer);
console.log('转换后第一个字节:', newView.getUint8(0)); // 100

3. 注意事项

  1. 内存共享:通过uint8Array.buffer获取的ArrayBuffer与原始Uint8Array共享内存,修改一个会影响另一个。

  2. 独立内存:如果需要独立的内存空间,可以使用slice()方法或创建新的ArrayBuffer。

  3. 数据完整性:转换过程中数据不会丢失,但需要注意字节顺序(大端序/小端序)。

  4. 性能考虑:直接访问buffer属性性能最好,适合大数据量操作。

4. 实际应用场景

  • 文件读写:处理文件二进制数据
  • 网络通信:处理网络传输的二进制数据
  • 图像处理:操作图像像素数据
  • 加密解密:处理加密的二进制数据

通过掌握ArrayBuffer和Uint8Array的相互转换,可以更灵活地处理鸿蒙应用中的二进制数据操作。


更多关于HarmonyOS鸿蒙Next应用开发arrayBuffer和Uint8Array互相转化的实战教程也可以访问 https://www.itying.com/category-93-b0.html

4 回复

一、结论

ArrayBuffer ArrayBuffer内部包含一块Native内存,该ArrayBuffer的JS对象壳被分配在虚拟机本地堆(LocalHeap)。与普通对象一样,需要经过序列化与反序列化拷贝传递,但是Native内存有两种传输方式:拷贝和转移。

Uint8Array Uint8Array是一种基本的JavaScript数组类型,用于处理二进制数据。它是无符号的8位整数数组,每个元素固定为1字节(8位)。这种数组类型主要用于操作二进制数据,如文件、图像数据或网络通信中的原始数据。

在鸿蒙(HarmonyOS)开发中,Uint8Array经常被用来处理二进制数据,例如在证书管理模块中,它被用来表示签名结果或证书二进制数据。由于Uint8Array能够有效地处理二进制数据,它在处理网络通信或文件操作时非常有用,可以提高性能并减少内存使用。

二、代码实现和详细解释

export class Util {

  /**
   * arrayBuffer转Uint8Array
   * @param buffer
   * @returns
   */
  public arrayBufferToUint8Array(buffer: ArrayBuffer): Uint8Array {
    let temp = new Uint8Array(buffer);
    return temp;
  }

  /**
   * uint8Array转ArrayBuffer
   * @param buffer
   * @returns
   */
  public uint8ArrayToArrayBuffer(array: Uint8Array): ArrayBuffer {
    let temp = array.buffer as ArrayBuffer;
    return temp;
  }
  
}

更多关于HarmonyOS鸿蒙Next应用开发arrayBuffer和Uint8Array互相转化的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


1. ArrayBuffer

  • 定义ArrayBuffer 是鸿蒙 ArkTS TypedArray(如 Int8ArrayUint8Array 等)的底层数据结构,用于表示固定长度的原始二进制数据缓冲区。它内部包含一块 Native 内存,JS 对象壳分配在虚拟机本地堆(LocalHeap)1。
  • 特性
    • 仅存储原始字节,不直接操作数据。
    • 传输数据时支持两种方式:拷贝(复制内存)或转移(移动内存所有权)。
  • 关键属性
    byteLength: number  // 只读属性,表示缓冲区占用的字节数
    
  • 构造方式
    // 创建指定字节长度的ArrayBuffer(最大长度不超过2147483647)
    let arrayBuffer: collections.ArrayBuffer = new collections.ArrayBuffer(10);
    

2. Uint8Array

  • 定义Uint8Array 是一种基于 ArrayBuffer 的线性数据结构,属于 ArkTS TypedArray23。它表示一个8位无符号整数数组(每个元素占1字节),用于高效操作二进制数据(如文件、图像、网络数据)1。
  • 特性
    • 元素值范围:0255
    • 直接关联 ArrayBuffer,可通过视图访问或修改底层二进制数据。
  • 关键属性
    buffer: ArrayBuffer     // 只读,关联的底层ArrayBuffer
    byteLength: number      // 只读,Uint8Array占用的字节数
    byteOffset: number      // 只读,在ArrayBuffer中的起始偏移量
    BYTES_PER_ELEMENT: number // 只读,每个元素占用的字节数(固定为1)
    
  • 构造方式
    // 方式1:创建空Uint8Array
    let uint8Array1 = new collections.Uint8Array();
    
    // 方式2:创建指定长度的Uint8Array
    let uint8Array2 = new collections.Uint8Array(12);
    
    // 方式3:从ArrayBuffer构造(可指定偏移和长度)
    let arrayBuffer = new collections.ArrayBuffer(10);
    let uint8Array3 = new collections.Uint8Array(arrayBuffer, 1, 5);
    
    // 方式4:从数组或可迭代对象构造
    let uint8Array4 = collections.Uint8Array.from([1, 2, 3]);
    

3. 二者关系

  • 依赖关系Uint8ArrayArrayBuffer视图(View),提供了操作底层二进制数据的接口。
  • 数据共享: 多个 Uint8Array 可共享同一个 ArrayBuffer,修改视图会影响底层缓冲区的数据。
  • 转换方法
    // ArrayBuffer → Uint8Array
    public arrayBufferToUint8Array(buffer: ArrayBuffer): Uint8Array {
      return new Uint8Array(buffer);
    }
    
    // Uint8Array → ArrayBuffer
    public uint8ArrayToArrayBuffer(array: Uint8Array): ArrayBuffer {
      return array.buffer; // 直接返回关联的ArrayBuffer
    }
    

在HarmonyOS鸿蒙Next应用开发中,arrayBuffer与Uint8Array的互相转化可通过以下方式实现:

  1. ArrayBuffer转Uint8Array

    let buffer: ArrayBuffer = new ArrayBuffer(16);
    let uint8Array: Uint8Array = new Uint8Array(buffer);
    
  2. Uint8Array转ArrayBuffer

    let uint8Array: Uint8Array = new Uint8Array([1, 2, 3]);
    let buffer: ArrayBuffer = uint8Array.buffer;
    

以上操作基于TypeScript/ArkTS,直接使用标准API完成转换。

在HarmonyOS Next应用开发中,ArrayBufferUint8Array 是处理二进制数据的基础。

ArrayBuffer 是一个通用的、固定长度的原始二进制数据缓冲区。它本身不能直接读写,而是作为“内存区域”的引用。

Uint8Array 是一种类型化数组(TypedArray),表示一个由8位无符号整数组成的数组。它提供了一个“视图”,通过这个视图可以读写底层 ArrayBuffer 中的数据。

互相转化源码:

  1. ArrayBuffer 转 Uint8Array: 这是最常见的操作,通过创建 Uint8Array 视图来访问 ArrayBuffer

    let buffer = new ArrayBuffer(16); // 创建一个16字节的buffer
    let uint8Array = new Uint8Array(buffer); // 创建视图,此时uint8Array与buffer共享同一块内存
    
  2. Uint8Array 转 ArrayBuffer: Uint8Array 实例本身就有一个 .buffer 属性,它返回其底层的 ArrayBuffer。需要注意的是,这个 ArrayBuffer 可能只表示 Uint8Array 所使用的一部分内存(即从 byteOffset 开始,长度为 byteLength 的区域)。

    let uint8Array = new Uint8Array([1, 2, 3, 4, 5]);
    let buffer = uint8Array.buffer; // 获取底层ArrayBuffer
    
    // 如果你需要一个新的、只包含Uint8Array数据的完整ArrayBuffer,可以使用slice
    let newBuffer = uint8Array.slice().buffer; // 或 uint8Array.subarray().buffer
    // slice()创建了一个新的Uint8Array副本,其.buffer就是对应的新ArrayBuffer
    

关键点:

  • new Uint8Array(buffer) 创建的是“视图”,它们操作的是同一块内存。修改 uint8Array 的内容,buffer 里的数据也会同步变化。
  • uint8Array.buffer 获取的是其底层关联的 ArrayBuffer 对象,如果该 Uint8Array 是从一个更大的 ArrayBuffer 切片(slice/subarray)而来,那么 .buffer 返回的将是原始的那个更大的 ArrayBuffer
  • 如果需要完全独立分离的 ArrayBuffer,应先通过 slice() 方法复制 Uint8Array,再获取其 .buffer
回到顶部