【HarmonyOS NEXT】鸿蒙arrayBuffer和Uint8Array互相转化

发布时间:2026/7/17 19:58:00
【HarmonyOS NEXT】鸿蒙arrayBuffer和Uint8Array互相转化 一、概念溯源ArrayBuffer与Uint8Array的本质在鸿蒙HarmonyOS NEXT应用开发中二进制数据的处理是绕不开的基础能力。无论是网络通信、文件读写、图片处理还是加解密都会与ArrayBuffer和Uint8Array打交道。1.1 ArrayBuffer原始的内存块ArrayBuffer代表一块固定长度的原始二进制数据缓冲区。可以把它想象成一块未经开垦的内存区域它只负责占有一块连续的内存空间但不提供任何手段来直接读写其中的数据。特点固定长度创建后无法直接增减大小本身不可读写必须通过“视图”来操作。创建方式typescript// 创建一个长度为8字节的ArrayBuffer const buffer: ArrayBuffer new ArrayBuffer(8); console.log(buffer.byteLength); // 输出: 8在鸿蒙系统中ArrayBuffer内部包含一块Native内存其JS对象壳被分配在虚拟机本地堆LocalHeap上。作为一种可转移对象ArrayBuffer在线程间传递时无需拷贝能有效减少内存占用、提升性能。1.2 Uint8Array操作内存的视图Uint8Array是一种类型化数组TypedArray它充当ArrayBuffer的“视图”将缓冲区的数据解析为8位无符号整数数组。本质它并不拥有自己的数据而是引用底层的ArrayBuffer。每个元素对应1个字节8位取值范围为0~255。常见用途处理文件数据、图像像素、网络协议包、证书二进制数据等。typescript// 从已有的ArrayBuffer创建Uint8Array视图 const buffer new ArrayBuffer(8); const uint8Array new Uint8Array(buffer); // 此时uint8Array引用了buffer修改uint8Array[0]会直接影响buffer理解两者的关系ArrayBuffer是“内存条”Uint8Array是“读懂内存条上字节的工具”。二、核心转换互转的两种场景2.1 ArrayBuffer → Uint8Array将ArrayBuffer转化为Uint8Array是获取数据视图的过程可以通过构造方法直接实现typescript/** * ArrayBuffer转Uint8Array * param buffer 原始二进制缓冲区 * returns 对应的Uint8Array视图 */ function arrayBufferToUint8Array(buffer: ArrayBuffer): Uint8Array { // 方法1直接构造共享内存 return new Uint8Array(buffer); // 方法2若需独立副本不共享内存使用slice // return new Uint8Array(buffer.slice(0)); }注意事项通过new Uint8Array(buffer)创建的视图与buffer共享同一块内存修改视图中的数据会同步影响原ArrayBuffer。2.2 Uint8Array → ArrayBufferUint8Array内部维护着对底层ArrayBuffer的引用通过.buffer属性即可获取typescript/** * Uint8Array转ArrayBuffer * param array Uint8Array实例 * returns 对应的ArrayBuffer */ function uint8ArrayToArrayBuffer(array: Uint8Array): ArrayBuffer { // 方法1直接访问buffer属性共享内存 return array.buffer as ArrayBuffer; // 方法2若需独立副本不共享内存需手动复制 // const newBuffer new ArrayBuffer(array.length); // const view new Uint8Array(newBuffer); // view.set(array); // return newBuffer; }注意事项array.buffer返回的ArrayBuffer与原Uint8Array共享内存。如需独立副本需手动创建新的ArrayBuffer并用set()复制数据。2.3 工具类封装可直接复用typescriptexport class BinaryUtil { /** * ArrayBuffer转Uint8Array */ public static arrayBufferToUint8Array(buffer: ArrayBuffer): Uint8Array { return new Uint8Array(buffer); } /** * Uint8Array转ArrayBuffer */ public static uint8ArrayToArrayBuffer(array: Uint8Array): ArrayBuffer { return array.buffer as ArrayBuffer; } /** * 复制一份独立的Uint8Array不共享内存 */ public static cloneUint8Array(src: Uint8Array): Uint8Array { const buffer new ArrayBuffer(src.length); const dst new Uint8Array(buffer); dst.set(src); return dst; } /** * 复制一份独立的ArrayBuffer不共享内存 */ public static cloneArrayBuffer(src: ArrayBuffer): ArrayBuffer { const dst new ArrayBuffer(src.byteLength); const srcView new Uint8Array(src); const dstView new Uint8Array(dst); dstView.set(srcView); return dst; } }三、进阶实战常见业务场景3.1 字符串与二进制互转文件读写、网络请求在鸿蒙中处理文本文件或网络数据时常需在字符串和二进制之间转换。核心利用util模块的TextEncoder和TextDecodertypescriptimport { util } from kit.ArkTS; // 字符串 → ArrayBuffer编码 function stringToArrayBuffer(str: string): ArrayBuffer { const encoder new util.TextEncoder(); const uint8Array encoder.encodeInto(str); // 返回Uint8Array return uint8Array.buffer as ArrayBuffer; } // ArrayBuffer → 字符串解码 function arrayBufferToString(buffer: ArrayBuffer, encoding: string utf-8): string { const decoder util.TextDecoder.create(encoding, { ignoreBOM: true }); const uint8Array new Uint8Array(buffer); return decoder.decodeWithStream(uint8Array, { stream: false }); }典型场景读取GBK编码的网络数据时先将响应数据作为ArrayBuffer获取再通过TextDecoder指定gbk解码为可读字符串。3.2 Base64与二进制互转图片传输、存储鸿蒙kit.ArkTS提供了Base64Helper配合二进制互转实现Base64编解码typescriptimport { util } from kit.ArkTS; const base64Helper new util.Base64Helper(); // ArrayBuffer → Base64 function arrayBufferToBase64(buffer: ArrayBuffer): string { const uint8Array new Uint8Array(buffer); return base64Helper.encodeToStringSync(uint8Array); } // Base64 → ArrayBuffer function base64ToArrayBuffer(base64Str: string): ArrayBuffer { const uint8Array: Uint8Array base64Helper.decodeSync(base64Str); return uint8Array.buffer as ArrayBuffer; }3.3 图片Uri/文件转ArrayBuffer从图片URI或文件路径读取二进制数据可用于上传或图像处理typescriptimport { fileIo as fs } from kit.CoreFileKit; function uriToArrayBuffer(uri: string): ArrayBuffer { const file fs.openSync(uri, fs.OpenMode.READ_ONLY); // 先获取文件大小更精确 const stat fs.statSync(file.fd); const buffer new ArrayBuffer(stat.size); fs.readSync(file.fd, buffer); fs.closeSync(file.fd); return buffer; }3.4 PixelMap与ArrayBuffer互转图像处理处理图像像素数据时可在PixelMap与ArrayBuffer间转换typescriptimport { image } from kit.ImageKit; // PixelMap → ArrayBuffer function pixelMapToArrayBuffer(pm: image.PixelMap): ArrayBuffer { const buffer new ArrayBuffer(pm.getPixelBytesNumber()); pm.readPixelsToBufferSync(buffer); return buffer; } // ArrayBuffer → PixelMap需结合ImageSource function arrayBufferToPixelMap(buffer: ArrayBuffer): image.PixelMap { const imageSource image.createImageSource(buffer); return imageSource.createPixelMapSync({ desiredPixelFormat: image.PixelMapFormat.RGBA_8888 }); }3.5 与Native层交互ArkTS → C在鸿蒙跨语言调用中Native层收到的是Uint8Array类型参数通过.buffer获取ArrayBuffer后可传递给C层处理typescript// ArkTS侧 function passToNative(data: Uint8Array): void { const buffer data.buffer; // 获取ArrayBuffer // 调用Native接口传递buffer nativeModule.processData(buffer); }四、深度注意内存共享与独立副本这是最容易踩的坑——转换时内存是否共享。转换方式内存关系修改是否互相影响new Uint8Array(buffer)共享✅ 是uint8Array.buffer共享✅ 是buffer.slice(0)再构造独立❌ 否手动new ArrayBufferset()独立❌ 否何时需要独立副本序列化/反序列化传输时不希望数据被意外篡改跨线程传递时原数据可能被回收或修改需要对数据进行修改但不想影响原始缓冲区创建独立副本的标准写法typescript// 从Uint8Array创建独立ArrayBuffer function createIndependentBuffer(src: Uint8Array): ArrayBuffer { const dst new ArrayBuffer(src.length); const dstView new Uint8Array(dst); dstView.set(src); // 复制数据 return dst; }五、总结速查表需求代码示例ArrayBuffer → Uint8Array共享new Uint8Array(buffer)Uint8Array → ArrayBuffer共享uint8Array.bufferArrayBuffer → Uint8Array独立new Uint8Array(buffer.slice(0))Uint8Array → ArrayBuffer独立const b new ArrayBuffer(a.length); new Uint8Array(b).set(a);字符串 → ArrayBuffernew util.TextEncoder().encodeInto(str).bufferArrayBuffer → 字符串util.TextDecoder.create(utf-8).decodeWithStream(new Uint8Array(buffer))Base64 → ArrayBuffernew util.Base64Helper().decodeSync(str).bufferArrayBuffer → Base64new util.Base64Helper().encodeToStringSync(new Uint8Array(buffer))理解ArrayBuffer和Uint8Array的关系是鸿蒙二进制编程的基石。简单转换用.buffer和new Uint8Array()即可涉及数据独立性时需手动复制。结合util模块的编解码能力可覆盖绝大多数日常开发场景。