JavaScript 中何处使用 ArrayBuffer 与类型化数组?

2024-04-23

我正在从 Node.js 迁移到浏览器环境,但我仍然对 ArrayBuffer 与类型化数组(例如 Uint8Array)感到困惑。

我对在哪里使用类型化数组以及在哪里直接使用 ArrayBuffer 感到困惑。将一种转换为另一种并不难,反之亦然,但何时使用哪一种呢?

例如,当我创建一个代表代码中数据块的对象时,它应该是 ArrayBuffer 还是 Uint8Array?它取决于什么?

或者:我应该返回吗ArrayBuffer来自我的函数(例如,对于外部 API),还是类型化数组?

请注意,我可以通过谷歌搜索如何准确地将元素等添加到这些类型化数组中;我缺少的是一些简短的一般指南,说明在哪里使用什么。特别是当从节点的缓冲区移动时。


Concepts

数组缓冲区 https://devdocs.io/javascript/global_objects/arraybuffers 表示物理内存中的字节数组。 ArrayBuffer 是字节的实际存储,但很少直接使用 - 事实上,您无权直接读取 ArrayBuffer 的内容,只能传递它的引用。另一方面,它们用于服务器和客户端之间的二进制数据传输,或者通过 Blob 从用户的文件系统传输二进制数据。

ArrayBuffer byte array in memory
ArrayBuffer byte array in memory - each index equals one byte. ArrayBuffer is aligned in memory.

要读取 ArrayBuffer 的内容,您需要使用view。它位于顶部并提供一个“api”来通过不同宽度类型或任意访问字节。

宽度相关的视图

根据您的需要使用不同的视图。如果您只需要读取字节值,即。 -128 到 127 之间的有符号值 - 或 0-255 之间的无符号值,您将使用 Int8Array 或 Uint8Array。请注意,它们的名称有点“误导”,因为它们是视图而不是数组,并且仅引用底层 ArrayBuffer。

同样,您有以下观点:整型8数组 https://devdocs.io/javascript/global_objects/int8array, Uint8Array https://devdocs.io/javascript/global_objects/uint8array, Uint8ClampedArray https://devdocs.io/javascript/global_objects/uint8clampedarray, Int16数组 https://devdocs.io/javascript/global_objects/int16array, Uint16数组 https://devdocs.io/javascript/global_objects/uint16array, Int32数组 https://devdocs.io/javascript/global_objects/int32array, Uint32Array https://devdocs.io/javascript/global_objects/uint32array, 浮点32数组 https://devdocs.io/javascript/global_objects/float32array and Float64数组 https://devdocs.io/javascript/global_objects/float64array.

除了 *int8Arrays 之外,其他数组都对 ArrayBuffer 大小有一些要求。例如,Uint32Array 视图必须位于可被 4 整除的 ArrayBuffer 之上,否则会引发错误。 *int 16 视图需要两字节边界。

这通常不是问题,因为您可以直接使用视图的构造函数指定索引数量,并且将自动创建匹配的 ArrayBuffer 来满足这些要求。

由于 ArrayBuffer 是一个字节数组,*int16 视图从中读取两个字节 - 或者,一个索引 = 两个字节,*int32 四个,或一个索引 = 四个字节,依此类推。

Uint8Array 和 Uint8ClampedArray 之间的主要区别在于,超出范围的值会与普通数组进行模运算(例如 256 变为 0)。在钳位数组中,值按照建议进行钳位(256 变为 255)。

*int16 view
Int16/Uint16 views - each index represents two bytes and is memory aligned.

*int32 view
Int32/Uint32 and Float32 views - each index represents four bytes and is memory aligned.

Float64 view
Float64 view - each index represents eight bytes and is memory aligned.

DataView 的灵活性

然后是数据视图。这适用于需要灵活的 ArrayBuffer 并需要从缓冲区中不一定是宽度或内存对齐的位置读取可变宽度和位置的情况。

例如,*int32 索引将始终指向可被四整除的内存位置。另一方面,DataView 可以从位置 5 读取 Uint32,并将在内部处理所有需要的步骤(移位、屏蔽等),但代价是微小的开销。

另一个区别是 DataView 不使用索引,而是使用其表示的数据的绝对字节位置,并且它具有自己的方法来从任何位置读取或向任何位置写入各种宽度。

DataView
DataView - can read from any position and any width.

在其他情况下,您可以使用引用相同底层 ArrayBuffer 的多个不同视图。

目前没有整数的 64 位视图,但似乎有提议用于 ES8 https://github.com/sirisian/ecmascript-types.

共享数组缓冲区

提及新功能也很有用共享数组缓冲区 https://devdocs.io/javascript/global_objects/sharedarraybuffer可以在网络工作者之间使用。

你可以(并且仍然可以)使用可转让物品 https://devdocs.io/dom/transferable过去在某些浏览器中,但 SharedArrayBuffers 的效率更高,因为内存保持不变,只传输有关它的信息。 SharedArrayBuffers 不能像 ArrayBuffers 那样分离。

目的和使用领域

类型化数组适合存储特定的数值并且速度很快。位图是类型化数组的典型候选者(例如 canvas 2D/WebGL)。

网络工作者内部的数据的大量数据处理是另一种用途,等等。我已经提到了客户端和服务器或文件系统之间的二进制传输。

DataView 非常适合解析或构建二进制文件和文件格式。

类型化数组是打包二进制数据的绝佳方法,以便通过网络发送到服务器或通过 Web 套接字以及 WebRTC 数据通道等方式发送。

如果您处理音频、视频、画布或媒体记录,通常无法绕过使用类型化数组。

使用类型化数组的关键是性能和内存。它们最常用于特殊场景,但是当您只需要存储数值(或 utf-8 字符串、加密向量等)时,在普通情况下使用它们并没有什么问题。它们速度快且内存占用少。

防范措施

有一些预防措施需要注意:

字节顺序

必须对字节顺序采取一些预防措施。类型化数组始终反映它们运行的​​ CPU 架构,即。小端或大端。大多数消费者系统都是小端字节序,但在使用 *int16 和 *int32 数组时,必须特别注意字节顺序。 DataView 也可以帮助完成这部分,但如果性能很重要的话,它并不总是一个好的选择。

从服务器接收数据时,字节顺序也很重要。它们通常始终采用大端格式(也称为“网络顺序”)。对于解析文件格式同样适用。

浮点数编码

Float32/Float64 将读取和写入编码在IEEE-754 https://en.wikipedia.org/wiki/IEEE_floating_point格式。如果多个视图用于同一个缓冲区,这也是需要注意的事情。

跨浏览器支持

大多数浏览器支持类型化数组 http://caniuse.com/#search=typed%20arrays如今。如果您必须使用较旧的浏览器,则必须返回 IE9 或较旧的移动浏览器,否则将无法使用它们。

Safari 在性能方面并没有特别优化,但其他好处还是有的。 5.1 版本不支持 Float64。

移动设备有其自身的硬件限制,但总的来说:类型化数组可以安全使用。对于特殊情况,存在一个polyfill https://github.com/inexorabletash/polyfill/blob/master/typedarray.js.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JavaScript 中何处使用 ArrayBuffer 与类型化数组? 的相关文章

  • 使用 jquery 远程图像属性

    目前我正在尝试获取远程图像宽度 高度 我正在开发一个链接共享模块 就像当你在 Facebook 上粘贴链接时 你可以看到标题 描述和图像 所以我尝试使用 php getimagesize 来获取图像宽度 高度 但速度非常慢 所以我正在考虑使
  • 如何使用 JavaScript 创建链接?

    我有一个标题字符串和一个链接字符串 我不知道如何将两者放在一起以使用 JavaScript 在页面上创建链接 任何帮助表示赞赏 我试图解决这个问题的原因是因为我有一个 RSS 源并且有一个标题和 URL 列表 我想将标题链接到 URL 以使
  • 为什么 iife 在一个简单的例子中不起作用?

    我不明白为什么函数表达式调用不起作用并抛出错误 你能给我解释一下吗 var a function x alert x function a 1 谢谢大家 任务比我想象的要容易得多 这是因为 JS 将 IIFE 解析为函数的参数调用 这样做时
  • 以编程方式填写reactjs表单

    我正在编写一个用户脚本 但无法填写由reactjs制作的表单 我的代码 document querySelector id username value email protected cdn cgi l email protection
  • IE从哪个版本开始支持Object.create(null)?

    您可以通过多种方式在 JavaScript 中创建对象 creates an object which makes the Object prototype of data var data1 new Object Object liter
  • 如何在react-bootstrap中禁用表单提交的

    在下面的代码片段中 我有许多文本类型的输入表单 如果用户点击 我似乎会得到相同的合成事件 就像他们按下提交按钮一样 我想忽略作为表单提交 只允许一个人按下 提交 按钮 我删除了一些表单组以减少示例 在所有情况下 按钮或 ENTER 键 e
  • Chrome 中的性能问题

    我目前正在从事一个相对较大的项目 使用 AngularJs 构建 应用程序的一部分是一个表单 您可以向其中添加任意数量的页面 不幸的是 添加了很多不必要的垃圾 即表示表单模型的对象可能会变得非常大 在某些时候 Chrome 基本上无法处理它
  • 如何针对 Node.js 中发生的每个错误发送电子邮件?

    假设我的 node js 应用程序正在运行 如果出现错误 我的意思是所有错误 不仅仅是网络错误 如果出现错误 则很重要 我如何调用函数向我发送电子邮件 基本上 在我希望它写入 err out 之前 我希望向我发送一封电子邮件 我正在使用no
  • 可以在初始 DOM 解析期间/之前修改 DOM 吗?

    是否可以在初始 DOM 解析期间或之前修改 DOM 或者我是否必须等到 DOM 被解析和构建之后才能与其交互 更具体地说 是否有可能阻止 DOM 中的脚本元素使用用户脚本 内容脚本或 Chrome 或 Firefox 中的类似脚本运行 在解
  • 有没有办法使用 Rspec/Capybara/Selenium 将 javascript console.errors 打印到终端?

    当我运行 rspec 时 是否可以让 capybara selenium 向 rspec 报告任何 javascript console errors 和其他异常 我有一大堆测试失败 但当我手动测试它时 我的应用程序正在运行 如果不知道仅在
  • 将 GMT 时间转换为当地时间

    我以这种格式从我的服务器获取 GMT 时间 Fri 18 Oct 2013 11 38 23 GMT 我的要求是使用Javascript将此时间转换为本地时间 例如 如果用户来自印度 首先我需要采用时区 5 30并将其添加到我的服务器时间并
  • 设置 cookie 时中断 JavaScript 执行

    当设置 cookie 时 是否可以始终中断浏览器开发人员工具中的 javascript 执行 无需显式设置 JS 断点 document cookie 在 html head 块的开头添加此代码片段效果很好
  • 尝试将数据存储在点击器网站中

    我正在尝试存储一个名为的变量score无论何时刷新 您都会一次又一次地使用它 我不明白的是它的代码是什么 我尝试了一些方法 但似乎都不起作用 这是我的答题器网站 但是当我尝试使用 JavaScript 来存储它时 它不起作用window o
  • 为什么我们在打字稿中使用 HTMLInputElement ?

    我们为什么使用 document getElementById ipv as HTMLInputElement value 代替 document getElementById ipv value 功能getElementById返回具有类
  • Vue 和 Vuex:处理依赖的计算属性

    我的应用程序是一个使用 Vuex 在 Vue 中构建的精简电子表格 关键组件是TableCollection Table and Row The TableCollection有一个包含多个的数组Table对象 每个Table有一个包含多个
  • 在 Javascript 中连接空数组

    我正在浏览一些代码 我想知道这有什么用处 grid push concat row 根据我的理解 它等同于 grid push row 为什么要大惊小怪 连接 你想使用 concat当您需要展平数组并且没有由其他数组组成的数组时 例如 va
  • 如何隐藏/禁用 Highcharts.js 中的图例框?

    我想问是否可以使用 HighCharts js 库隐藏图表中的所有图例框 var chart object chart renderTo render to type graph type colors graph colors title
  • 在 CKEditor 中设置字体大小和字体系列

    我正在使用 ckeditor 我想问一下这个插件如何设置font family和font size 我尝试过使用 CKEDITOR config font defaultLabel Arial CKEDITOR config fontSiz
  • JavaScript 相对路径

    在第一个 html 文件中 我使用了一个变量类别链接 var categoryLinks Career prospects http localhost Landa DirectManagers 511 HelenaChechik Dim0
  • 使用 MongoDB 和 Nodejs 插入和查询日期

    我需要一些帮助在 mongodb 和 nodejs 中按日期查找记录 我将日期添加到抓取脚本中的 json 对象 如下所示 jsonObj last updated new Date 该对象被插入到 mongodb 中 我可以看到如下 la

随机推荐

  • Docker“共享依赖关系”

    在阅读 Docker 的同时 我多次停下来 因为 Docker 容器不仅共享主机内核 而且如果可能的话 它们还共享通用的二进制文件和库 我从中了解到的是 如果我在同一台主机上运行相同的 docker 映像两次 并且该映像使用一些文件 x y
  • 如何生成具有指定增量步骤的列表?

    如何生成具有指定增量步长 例如 2 的向量 例如 我如何生成以下内容 0 2 4 6 8 10 执行中seq 1 10 1 做什么1 10做 您可以更改最后一个参数seq i e by 任意大小的台阶 gt a vector of even
  • R中有“暂停”功能吗? [复制]

    这个问题在这里已经有答案了 我正在编写一个用户定义的函数 其中包含一个 for 循环 并且希望在每次迭代后暂停执行 是否有一些函数可以执行此操作 例如 MATLAB 中的 暂停 是的 您可以使用以下命令暂停执行Sys sleep 因此 等待
  • 优雅的模式来记录用户的操作

    我有一个数据库架构来记录用户在我的网络应用程序中执行的操作 Log Id Log Type Id Performed by Person Id Performed to Person Id Comment Id Story Id Photo
  • SQL Server:索引重建和索引重组有什么区别?

    指数重建和指数重组有什么区别 思考一下索引是如何实现的 它通常是某种树 例如 B 树或 B 树 索引本身是通过查看数据中的键并构建树来创建的 以便可以有效地搜索表 当你改组索引 您遍历现有索引 清理已删除记录的块等 这could当您进行删除
  • 如何在 Android 上直接从麦克风向扬声器播放声音?

    在我的应用程序中 我需要将声音从麦克风直接引导到扬声器 没有其他动作 我找到了一种通过播放文件并关闭扬声器将声音从麦克风引导到耳机的方法 所以我想扬声器可以类似地工作 但是我不知道如何摆脱播放文件的事情 谢谢 speaker m audio
  • unix系统上C++中的简单glob?

    我想检索遵循此模式的所有匹配路径vector
  • 如何防止gitlab ci每次都下载sbt?

    我们有一个play2 scala我们正在使用 gitlab ci 构建的应用程序 Our gitlab ci yml 至少重要部分 如下所示 image hseeberger scala sbt variables SBT GLOBAL B
  • 导入“google/api/annotations.proto”未找到或有错误。如何将其添加为依赖项?

    按照文档如何设置 gRPC 网关 https github com grpc ecosystem grpc gateway 我发现自己陷入了生成 grpc 网关的第四步 也就是说 当添加以下行时 事情就会崩溃 import google a
  • 如何让 Mechanize 自动将正文转换为 UTF8?

    我找到了一些解决方案post connect hook and pre connect hook 但似乎它们不起作用 我正在使用最新的 Mechanize 版本 2 1 没有 response 新版本中的字段 我不知道在新版本中从哪里获取它
  • 如何创建页面链接并在该页面的 iframe 中加载特定内容

    在我们的网站上 我们有一个页面可以将内容从另一个位置提取到 iFrame 中 我想知道如何创建指向父页面的链接并在 iFrame 中加载特定页面 所以 我想创建一个链接http xxx xxx com page http xxx xxx c
  • 如何在客户端 JavaScript 中读取本地 csv 文件?

    我有客户端 javascript 我想从本地读取它csv文件 在html代码中 我使用脚本标签导入本地javascript文件 并且该js文件位于另一个文件夹中 js文件的内容 ajax type GET url data English
  • 简单聚类算法 2D。检测点簇

    任何人都知道用 C 实现的简单算法来检测 2D 游戏中的怪物组 前任 char周围100范围内有怪物 我想检测哪些怪物在彼此范围 2 内 如果至少有 5 个在一起 则在该位置使用效果区域技能 否则使用单目标技能 最好有一个实现的链接 最好是
  • 在 matplotlib 中,有没有办法在条形/线条/补丁下方设置网格线,同时保留上面的刻度标签?

    相关Matplotlib 在其他图形元素后面绘制网格线 https stackoverflow com questions 1726391 matplotlib draw grid lines behind other graph elem
  • 读外国文字

    我有一个包含英超足球运动员姓名的数据库 我正在将其读入 R 3 02 但当涉及到姓名中含有外来字符 元音变音 重音符号等 的球员时 我遇到了困难 下面的代码说明了这一点 PlayerData lt read table C Users Do
  • 将 vec3b 转换为 mat

    我有彩色图像im 我想使用以下代码使用 vec3b 获取 3 通道图像的像素值 for int i 0 i lt im rows i for int j 0 j lt im cols j for int k 0 k lt nChannels
  • 在 Java 中显式调用默认方法

    Java 8 引入默认方法 http cr openjdk java net dlsmith jsr335 jsr335 0 6 2 H html提供扩展接口的能力 而无需修改现有的实现 我想知道当该方法已被覆盖或由于不同接口中的默认实现冲
  • 自动调整winform和控件到屏幕尺寸

    我创建了一个 winform 应用程序 每个屏幕的尺寸为1361 768像素 这对于较大的屏幕和 或笔记本电脑非常有用 但现在我必须将我的应用程序移至 10 英寸屏幕平板电脑 这意味着我的应用程序不适合 我以前从未处理过这个问题 如何在较小
  • R包安装时间长 - 源代码或二进制类型

    我正在尝试安装一个名为stringi使用下面的命令 install packages stringi 虽然它没有抛出任何错误消息 但安装尚未结束 我在控制台屏幕上看到很多消息 该屏幕持续运行超过 45 分钟 gt install packa
  • JavaScript 中何处使用 ArrayBuffer 与类型化数组?

    我正在从 Node js 迁移到浏览器环境 但我仍然对 ArrayBuffer 与类型化数组 例如 Uint8Array 感到困惑 我对在哪里使用类型化数组以及在哪里直接使用 ArrayBuffer 感到困惑 将一种转换为另一种并不难 反之