uni-app UTS 内置对象 ArrayBuffer 完全指南:跨端二进制数据处理与内存共享实战

发布时间:2026/9/19 17:44:38
uni-app UTS 内置对象 ArrayBuffer 完全指南:跨端二进制数据处理与内存共享实战 uni-app UTS 内置对象 ArrayBuffer 完全指南跨端二进制数据处理与内存共享实战【免费下载链接】uni-appA cross-platform framework using Vue.js项目地址: https://gitcode.com/gh_mirrors/un/uni-appArrayBuffer 是 uni-app 的 UTSUni-app TypeScript内置对象用于表示通用的原始二进制数据缓冲区是文件读取、网络请求、加解密、Base64 编解码等场景的底层基础设施。本文以 docs/uts/buildin-object-api/arraybuffer.md 为骨架结合仓库内的官方测试用例与插件源码完整讲解 ArrayBuffer 的构造、静态方法、实例方法、平台兼容性以及 JS 与 Swift 之间的零拷贝内存共享方案。读完本文你将能够在 uni-app xuvue页面与 UTS 插件中熟练地创建、读写、切片和跨语言传递二进制数据。ArrayBuffer 是什么ArrayBuffer 对象用来表示通用的原始二进制数据缓冲区。它是一个字节数组通常在其他语言中称为 byte array字节数组其基本语义与 JavaScript 标准的ArrayBuffer一致。关键约束是你不能直接操作 ArrayBuffer 中的内容。缓冲区本身只负责存字节要读写其中的数据必须借助两类视图对象它们将缓冲区中的数据表示为特定的格式类型化数组对象TypedArray以固定元素类型如 8 位整数、32 位浮点数读写缓冲区DataView 对象提供更灵活、可指定字节序的底层读写接口。在 docs/uts/data-type.md 的字节数组ArrayBuffer一节中UTS 数据类型体系也将 ArrayBuffer 列为内置类型并给出了初始化类型化数组的三种典型写法// 直接使用 ArrayBuffer 初始化类型化数组 const buffer new ArrayBuffer(8); const view new Int32Array(buffer); // 使用 of 方法 var array Int32Array.of(1, 2, 3) // 使用 from 方法 var array Int32Array.from([1, 2, 3], (v : number, _ : number) : number v v);UTS 内置的 9 种类型化数组对象与 DataView 对应文档均已存在于当前仓库Float32ArrayFloat64ArrayInt8ArrayInt16ArrayInt32ArrayUint8ArrayUint8ClampedArrayUint16ArrayUint32ArrayDataView构造函数创建指定字节长度的缓冲区通过new ArrayBuffer(byteLength)可以创建一个以字节为单位的给定长度的新 ArrayBuffer新缓冲区中的字节全部初始化为 0。| 名称 | 类型 | 必填 | 描述 | | :- | :- | :- | :- | | byteLength | number | 是 | 长度单位字节 |返回值| 类型 | 描述 | | :- | :- | | ArrayBuffer | 新建的 ArrayBuffer 对象 |兼容性uni-app xWeb √Android 4.25iOS √HarmonyOS 4.61iOS(VDOM) UTS 插件 4.51uni-app UTS 插件Android √iOS 4.51HarmonyOS √说明表格中√表示已支持带数字的版本号如 Android 4.25、HarmonyOS 4.61、iOS 4.51表示从该 HBuilderX/uni-app x 版本开始支持。本文后续所有 API 的兼容性表均为同一语义。静态方法ArrayBuffer 提供三个静态方法通用的isView以及两个平台原生对象转换方法fromByteBufferAndroid与fromDataiOS。isView(arg)判断值是否为 ArrayBuffer 视图ArrayBuffer.isView()用于确定传入的值是否是 ArrayBuffer 视图之一类型化数组对象或 DataView。| 名称 | 类型 | 必填 | 描述 | | :- | :- | :- | :- | | arg | any | 是 | 需要检测的值 |返回值boolean。如果 arg 是 ArrayBuffer 视图之一例如类型化数组对象或者 DataView则返回 true否则返回 false。var arrayBuffer new ArrayBuffer(16) var float64 new Float64Array(arrayBuffer); var isView ArrayBuffer.isView(float64) console.log(isView)//true var a 1 var isViewA ArrayBuffer.isView(a) console.log(isViewA)//false兼容性uni-app xWeb √Android 4.25iOS √HarmonyOS 4.61iOS(VDOM) UTS 插件 4.51uni-app UTS 插件Android √iOS 4.51HarmonyOS √fromByteBuffer(byteBuffer)Android 原生 ByteBuffer 转 ArrayBufferArrayBuffer.fromByteBuffer()用于将 Android 原生的ByteBuffer对象转换为 ArrayBuffer是 UTS 代码与 Android Java/Kotlin 生态交换二进制数据的关键桥梁。| 名称 | 类型 | 必填 | 描述 | | :- | :- | :- | :- | | byteBuffer | ByteBuffer | 是 | Android 原生 ByteBuffer 对象 |返回值ArrayBuffer。var byteBuffer ByteBuffer.allocate(100) byteBuffer.put(1) byteBuffer.put(2) var buffer ArrayBuffer.fromByteBuffer(byteBuffer) console.log(arraybuffer_toByteBuffer, buffer) var int8 new Int8Array(buffer) console.log(int8[0])//1 console.log(int8[1])//2 byteBuffer buffer.toByteBuffer() console.log(arraybuffer_toByteBuffer, byteBuffer) byteBuffer.rewind() console.log(byteBuffer[0])//1 console.log(byteBuffer[1])//2兼容性uni-app xWeb xAndroid 4.25iOS xHarmonyOS x即仅 Android 端可用uni-app UTS 插件Android √iOS xHarmonyOS xfromData(data)iOS 原生 Data 转 ArrayBufferArrayBuffer.fromData()用于将 iOS 原生的Data对象转换为 ArrayBuffer是 UTS 代码与 Swift 生态交换二进制数据的桥梁。| 名称 | 类型 | 必填 | 描述 | | :- | :- | :- | :- | | data | Data | 是 | iOS 原生 Data 对象 |返回值ArrayBuffer。let str hello world; let data str.data(using String.Encoding.utf8)! let arrayBuffer ArrayBuffer.fromData(data) let uint8Array new Uint8Array(arrayBuffer) console.log(uint8Array) let td arrayBuffer.toData() let content new String(decoding td, as UTF8.self) console.log(content)兼容性uni-app xWeb xAndroid xiOS xHarmonyOS xiOS(VDOM) UTS 插件 4.51即仅在 iOS 相关 UTS 插件环境中可用uni-app UTS 插件iOS 4.51HarmonyOS x实例属性byteLengthArrayBuffer实例的byteLength访问器属性返回该数组缓冲区的长度以字节为单位。const buffer new ArrayBuffer(16) console.log(buffer.byteLength) // 16兼容性uni-app xWeb √Android 4.25iOS 4.11HarmonyOS 4.61iOS(VDOM) UTS 插件 4.51uni-app UTS 插件Android √iOS 4.51HarmonyOS √实例方法slice(begin?, end?)截取字节副本ArrayBuffer实例的slice()方法返回一个新的 ArrayBuffer 实例其包含原 ArrayBuffer 中从begin开始包含到end结束不含的所有字节的副本。注意返回的是副本与原缓冲区不共享内存。| 名称 | 类型 | 必填 | 描述 | | :- | :- | :- | :- | | begin | number | 否 | 要开始提取的位置索引从 0 开始将被转换为整数。负数索引从缓冲区末尾开始计算——如果 begin 0则使用 begin buffer.length如果 begin -buffer.length 或省略了 begin则使用 0如果 begin buffer.length则不提取任何内容 | | end | number | 否 | 要结束提取的位置索引从 0 开始将被转换为整数slice() 提取到但不包括 end。负数索引从缓冲区末尾开始计算——如果 end 0则使用 end buffer.length如果 end -buffer.length则使用 0如果 end buffer.length 或省略了 end则使用 buffer.length导致直到末尾的所有元素都被提取如果标准化后的 end 位置在 begin 位置之前则不提取任何内容 |返回值ArrayBuffer一个新的 ArrayBuffer 对象。各种类型化数组视图下的 slice 示例let buffer new ArrayBuffer(16); let float32 new Float32Array(buffer); float32[3] 42; console.log(float32.toString()); // 0,0,0,42 let res buffer.slice(8); let sliced new Float32Array(res); console.log(sliced[1]); // 42 let buffer new ArrayBuffer(16); let float64 new Float64Array(buffer); float64[1] 42; console.log(float64.toString()); // 0,42 let res buffer.slice(8); let sliced new Float64Array(res); console.log(sliced[0]); // 42 let buffer new ArrayBuffer(16); let int32 new Int32Array(buffer); int32[3] 42; console.log(int32.toString()); // 0,0,0,42 let res buffer.slice(8); let sliced new Int32Array(res); console.log(sliced[1]); // 42 let buffer new ArrayBuffer(16); let int8 new Int8Array(buffer); int8[4] 42; console.log(int8.toString()); // 0,0,0,0,42,0,0,0,0,0,0,0,0,0,0,0 let res buffer.slice(4, 5); let sliced new Int8Array(res); console.log(sliced[0]); // 42 let buffer new ArrayBuffer(16); let uint8 new Uint8Array(buffer); uint8[4] 42; console.log(uint8.toString()); // 0,0,0,0,42,0,0,0,0,0,0,0,0,0,0,0 let res buffer.slice(4, 12); let sliced new Uint8Array(res); console.log(sliced[0]); // 42 let buffer new ArrayBuffer(16); let uint8Clamped new Uint8ClampedArray(buffer); uint8Clamped[4] 42; console.log(uint8Clamped.toString()); // 0,0,0,0,42,0,0,0,0,0,0,0,0,0,0,0 let res buffer.slice(4, 12); let sliced new Uint8ClampedArray(res); console.log(sliced[0]); // 42 let buffer new ArrayBuffer(16); let uint32 new Uint32Array(buffer); uint32[3] 42; console.log(uint32.toString()); // 0,0,0,42 let res buffer.slice(8); let sliced new Uint32Array(res); console.log(sliced[1]); // 42从上面的示例可以看出 slice 的字节语义16 字节缓冲区中Float32Array[3]、Int32Array[3]、Uint32Array[3]均落在偏移 8 字节处4 字节对齐的元素 3因此slice(8)后新视图的[1]就是 42而Int8Array[4]、Uint8Array[4]、Uint8ClampedArray[4]落在偏移 4 字节处使用slice(4, 5)或slice(4, 12)截取后新视图[0]即为 42。兼容性uni-app xWeb √Android 4.25iOS 4.11HarmonyOS 4.61iOS(VDOM) UTS 插件 4.51uni-app UTS 插件Android √iOS 4.51HarmonyOS √toByteBuffer()ArrayBuffer 转 Android 原生 ByteBufferArrayBuffer实例的toByteBuffer()方法返回一个 Android 原生ByteBuffer对象与fromByteBuffer()互为逆操作。返回值ByteBufferAndroid 原生 ByteBuffer 对象。var byteBuffer ByteBuffer.allocate(100) byteBuffer.put(1) byteBuffer.put(2) var buffer ArrayBuffer.fromByteBuffer(byteBuffer) console.log(arraybuffer_toByteBuffer, buffer) var int8 new Int8Array(buffer) console.log(int8[0])//1 console.log(int8[1])//2 byteBuffer buffer.toByteBuffer() console.log(arraybuffer_toByteBuffer, byteBuffer) byteBuffer.rewind() console.log(byteBuffer[0])//1 console.log(byteBuffer[1])//2兼容性uni-app xWeb xAndroid 4.25iOS xHarmonyOS xuni-app UTS 插件Android √iOS xHarmonyOS xtoData()ArrayBuffer 转 iOS 原生 DataArrayBuffer实例的toData()方法返回一个 iOS 原生Data对象与fromData()互为逆操作。返回值DataiOS 原生 Data 对象。let str hello world; let data str.data(using String.Encoding.utf8)! let arrayBuffer ArrayBuffer.fromData(data) let uint8Array new Uint8Array(arrayBuffer) console.log(uint8Array) let td arrayBuffer.toData() let content new String(decoding td, as UTF8.self) console.log(content)兼容性uni-app xWeb xAndroid xiOS xHarmonyOS xiOS(VDOM) UTS 插件 4.51uni-app UTS 插件iOS 4.51HarmonyOS x注意事项与平台限制使用 ArrayBuffer 时需特别留意以下三条限制它们在 docs/uts/buildin-object-api/arraybuffer.md 中明确给出默认以大端序Big-Endian存储数据。因此当与外部系统、文件格式或网络协议交换二进制数据时务必确认双方字节序一致必要时使用 DataView 的按字节序读写方法来保证正确性。iOS 的 uvue 页面编译成 js 时可以使用 ArrayBuffer而iOS 的 uts 插件对 ArrayBuffer 的支持从 HBuilderX 4.51 版本开始。也就是说在 iOS 端uts 插件环境中使用 ArrayBuffer 需要 4.51 及以上版本。Android 平台在 uni-app非 uni-app x上不支持将 ArrayBuffer 当作参数从 vue 传到插件里面但是可以在 vue 或者插件内部使用。设计插件 API 时如果面向 uni-app 的 vue 页面应避免要求调用方直接传入 ArrayBuffer 参数。进阶js 和 swift 基于 ArrayBuffer 的内存共享iOS 平台 uts 插件中的 ArrayBuffer 可以和 JS 中的 ArrayBuffer 实现内存共享零拷贝。即无论从 uvue 页面传递给 uts 插件的 ArrayBuffer还是从 uts 插件中返回给 js 的 ArrayBuffer都是指向同一个内存区域而不是拷贝一份后传递。这个特性在传递大内存内容时特别有用可以显著降低大文件、大图片等场景的内存开销与耗时。注意该特性在 Uni-app 和 Uni-app x 平台均支持。目前仅支持 js 和 Swift 之间通过 ArrayBuffer 的内存共享AndroidJava/Kotlin与 HarmonyOS 方向暂无此特性。下面以在 iOS 平台 uts 插件中读取大文件然后使用 ArrayBuffer 传递给 uvue 页面的场景为例演示该特性的完整实现。该示例的完整代码就位于仓库的hello-uts示例工程的SyntaxCase插件中readFile.swift 与 index.uts。第一步swift 文件中实现读取大文件函数混编示例import DCloudUTSFoundation // 注意如果你想在 uni-app 环境下运行此代码请将下面这行代码注释掉 import DCloudUniappRuntime class ReadFile { public static func readFile( _ path: String, _ completionHandler: ((ArrayBuffer?, NSNumber) - Void)? nil ) { // 转换路径 let absolutePath UTSiOS.convert2AbsFullPath(path) // 判断文件是否存在 if FileManager.default.fileExists(atPath: absolutePath) false { completionHandler?(nil, 1) return } // 将字符串路径转成 file url let fileUrl URL(fileURLWithPath: absolutePath) do { // 读取文件内容生成 swift 原生 Data let fileData try Data(contentsOf: fileUrl) // 将 Data 转成 ArrayBuffer, 注意ArrayBuffer 与 Data 的内存也是共享的内容的传递过程中也不存在内存复制。 let result ArrayBuffer.fromData(fileData) if result nil { completionHandler?(nil, 2) return } // 将 ArrayBuffer 回调出去 completionHandler?(result, 0) } catch { completionHandler?(nil, 1) } } }第二步在 uts 代码中定义读取文件的函数并对外暴露函数实现中调用上述 swift 文件中实现的方法// #ifdef APP-IOS export type ReadFileOptions { url: string, success: (res: ArrayBuffer) void, fail:(code: number) void } export function testBigArrayBuffer(option: ReadFileOptions) { // 调用 swift 实现读取指定路径的大文件并将生成的 ArrayBuffer 传递给 uvue 页面 (js环境) ReadFile.readFile(option.url, (res: ArrayBuffer | null, code: number) { if (code 0 res ! null) { option.success(res!) }else { option.fail(code) } }) } // #endif第三步在 uvue 页面中调用上述 uts 插件的 api并操作 ArrayBuffertestBigArrayBuffer({ url: /static/test.txt, success: (res) { console.log(读取成功) // 本示例中读取的是一个 1.4M 大小的.txt文件输出的长度是1391217 console.log(ArrayBuffer 长度,res.byteLength) }, fail: (code) { console.log(code) } })整个链路中SwiftData→ArrayBuffer.fromData()→ 回调给 JS全程共享同一块内存不存在内容复制res.byteLength直接输出 1391217证明 1.4M 的内容完整到达 js 侧。这一模式非常适合大文件解析、音视频帧处理、高带宽网络数据等对拷贝敏感的场景。源码中的真实应用ArrayBuffer 与 Base64 互转ArrayBuffer 在本仓库的官方 uni_modules 中被广泛用于平台能力封装最典型的是uni-arrayBufferToBase64与uni-base64ToArrayBuffer两个模块它们是理解toByteBuffer()/toData()实际用法的绝佳参考。Android 端实现src/uni_modules/uni-arrayBufferToBase64/utssdk/app-android/index.uts先调用arrayBuffer.toByteBuffer()拿到原生 ByteBuffer再读出字节数组交给android.util.Base64编码import { ArrayBufferToBase64 } from ../interface.uts import Base64 from android.util.Base64 export const arrayBufferToBase64 : ArrayBufferToBase64 function (arrayBuffer : ArrayBuffer) : string { // 将 ByteBuffer 转换为字节数组 const byteBuffer arrayBuffer.toByteBuffer() byteBuffer.position(0) const bytes new ByteArray(byteBuffer.remaining()) byteBuffer.get(bytes) // 读取内容到字节数组 // 使用 Base64 编码 return Base64.encodeToString(bytes, Base64.NO_WRAP) }iOS 端实现src/uni_modules/uni-arrayBufferToBase64/utssdk/app-ios/index.uts直接调用arrayBuffer.toData()得到原生 Data再调用其base64EncodedString()完成编码import { ArrayBufferToBase64 } from ../interface.uts export const arrayBufferToBase64 : ArrayBufferToBase64 function (arrayBuffer : ArrayBuffer) : string { // 将 ArrayBuffer 转成 Data const data arrayBuffer.toData() // 将 Data 转成 base64 字符串 return data.base64EncodedString() }可以看到fromByteBuffer/toByteBuffer、fromData/toData正是 UTS 与 Android/iOS 原生层对接时的标准转换通道统一了跨端二进制数据的表示。官方测试用例验证仓库hello-uts示例工程的测试插件中提供了 ArrayBuffer 的完整自动化测试examples/hello-uts/uni_modules/uts-tests/utssdk/ArrayBuffer.uts可用于验证 API 行为并作为自测参照arraybuffer_isview断言ArrayBuffer.isView(new Float64Array(buffer))为 true、ArrayBuffer.isView(1)为 falsearraybuffer_toByteBuffer仅 APP-ANDROID 编译完整覆盖fromByteBuffer→Int8Array读取 →toByteBuffer→rewind后按索引读取的往返链路断言写入的 1、2 在两端均能正确读回arraybuffer_toData仅 APP-IOS 编译覆盖fromData后经Uint8Array输出字节序列断言为104,101,108,108,111,32,119,111,114,108,100即hello world的 ASCII 码再经toData反解回字符串断言为hello world。测试中同样覆盖了ArrayBuffer.slice()配合各类型化数组的行为见各 TypedArray 测试中的arrayBufferSlice用例。这说明本仓库对 ArrayBuffer 的每个 API 都提供了可执行的行为验证开发者可以参照这些用例在自己的工程中做回归测试。总结ArrayBuffer 是 UTS 二进制编程的基石用new ArrayBuffer(byteLength)分配缓冲区通过 9 种 TypedArray 或 DataView 读写字节用slice()截取副本用byteLength获取长度在 Android 端通过fromByteBuffer()/toByteBuffer()与 Java 生态互转在 iOS 端通过fromData()/toData()与 Swift 生态互转。结合 iOS 平台独有的 js/Swift 内存共享特性可以在大文件、大块二进制数据的跨语言传递中实现零拷贝大幅降低内存与性能开销。使用时要牢记大端序默认存储、iOS 插件 4.51 版本门槛、Android uni-app 传参限制三条注意事项并根据各 API 的兼容性表确认目标平台与版本。【免费下载链接】uni-appA cross-platform framework using Vue.js项目地址: https://gitcode.com/gh_mirrors/un/uni-app创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询