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 与类型化数组? 的相关文章

  • 设置特定div的字符集

    是否可以为特定的 div 分配字符集 这样你就可以在一页上拥有多个字符集 我目前正在通过 JS 将文本片段导入到我的网站 其中一些文本需要 UTF 8 字符集 为了确保我的文本正确显示在包含的每个页面 有时是外部站点 上 我将元标记强制添加
  • 实时搜索错误

    我正在获取用户偏好和角色 一切正常并且数据接收正确 默认值放置在单选按钮上以突出显示用户当前拥有的选项 我正在使用 Antd Design Table 组件 问题 当我将用户首选项更改为打印文档时 它确实通过数据库的状态成功更改了它 但是现
  • 如何使用 vue-toastification

    我刚刚将在 vue 3 中创建的项目迁移到 nuxt 3 以前我使用了 vue toastification 模块 但现在我不知道如何正确导入它 我的代码使用这个模块 import useToast POSITION from vue to
  • 未记录的 Sheet API 限制问题

    我已经看过人们遇到类似问题的帖子 但找不到明确的答案 我尝试使用以下代码行检索 264735 个插槽的二维数组 var optionalArguments majorDimension ROWS valueRenderOption FORM
  • 无法安装组件:模板或渲染函数未定义。组件导入失败

    我正在尝试复制 vue 教程示例 在这里找到 https v3 vuejs org guide component basics html passing data to child components with props https
  • 来自 jquery 事件的回调角度函数

    我正在使用 Angular5 并尝试获取 fullcalendar io jquery 插件的 dayClick 事件来回调角度组件 以便我可以打开从日历详细信息填充的角度组件对话框 要设置示例 请在控制台中执行以下操作 ng new pj
  • 静态方法而不是原型方法Javascript

    当在类中调用实例函数时 对象的每个实例都会获得自己的函数副本 但在原型方法和静态方法中不会创建副本 它们属于类 所以如果它们都没有创建其函数的副本 那么为什么如果我们不想复制 可以简单地使用原型方法 那么我们是否有静态函数 我有点困惑 如果
  • 如何通知 AngularJS 表单已由 jQuery 外部填写?

    我在 AngularJS 中有一个页面 其中有一个包含一些字段的表单 加载该页面后 我想要一个书签 单击该书签可根据配置文件中的数据填充字段 正在使用一个 JS 文件 该文件使用 jquery 来填充表单中的数据 当我做 id val ab
  • FindAndUpdate 如何检查文档是否真的更新

    想象一下以下模型 var Office id 1 name My Office branches adddress Some street that avenue isPrincipal true adddress Another addr
  • Ajax - 下载前获取文件大小

    基本上 我想弄清楚是否应该使用 AJAX 下载文件 具体取决于文件大小有多大 我想这个问题也可以改写为 如何仅获取ajax请求的标头 EDIT ultima rat0 https stackoverflow com users 239962
  • 使 div 更大并在悬停时向上动画更大的部分

    当用户将鼠标悬停在 div 上时 我试图将 div 向上设置动画 我可以对 div 进行动画处理 使其变大 但动画是向下发生的 我试图将 div 的底部保持在同一位置 并平滑地向上增加 div 的大小 请参阅 jsfiddle 这里 htt
  • 打开 Chrome 扩展程序时出现 Service Worker TypeError

    当我打开 WAVE Web 可访问性评估工具 扩展时 我的服务工作人员在 Chrome 中抛出此错误 未捕获 承诺中 类型错误 请求方案 chrome extension 是 不支持的 在 sw js 52 匿名 sw js 52 Prom
  • 检测“文件下载”弹出窗口何时关闭

    我有一个网页 用 JSF 制作 其中一些链接允许用户获取 PDF 文件 当用户点击这样的链接时 会显示一个等待弹出窗口 它是一个模式面板 因为 PDF 的生成可能很长 并且一旦创建文件 IE 就会显示 文件下载 弹出窗口 建议 打开 保存
  • 如何将参数传递给backbone.js 中事件对象中绑定的函数

    我需要为 Backbone 中的事件对象中使用的函数提供参数 var DocumentRow Backbone View extend tagName li className document row events click icon
  • 窗口位置替换 - 超时帮助? JavaScript问题

    我曾尝试找到一种方法 在我的代码中添加超时 然后再重定向您 我用谷歌搜索并找到了一些帮助 但他们都没有达到我的预期 这会提示用户出生年份并计算年龄 大致 如果用户未满18岁 则带他们去迪士尼乐园 否则允许进入 函数年龄按钮 var AskD
  • Chrome 无法识别我对 javascript 文件的更改并加载旧代码?

    我在这里坐了将近一个小时来测试我正在构建的网站 由于我想查看代码中的新更改 因此我重新加载了代码 但它正在重新加载旧代码 我打开了 devetools 进行硬重新加载和清空缓存硬重新加载 它们都加载我的旧代码 我进入隐身模式 它做了同样的事
  • 从 Angularjs 应用程序中的 iOS Webview 调用 Javascript 函数

    我的问题是 当我尝试从 UIWebView 中调用 AngularJS 应用程序中存在的 javascript 函数时 该函数无法识别 当我在典型的 html 结构中调用该函数时 该函数会按预期被识别 下面提供的示例 目标 C void v
  • javascript 中的独立括号[重复]

    这个问题在这里已经有答案了 可能的重复 JavaScript 为什么使用匿名函数包装器 https stackoverflow com questions 1643321 javascript why the anonymous funct
  • Object.assign 方法不绑定“this”

    我正在尝试绑定this变量到一个新对象 function Parent sub component constructors this components node function this name jordan subcompone
  • 创建一个跨浏览器 mixin 进行转换:旋转

    我想为 sass 创建一个 mixin 它将对指定元素应用旋转 mixin 应采用一个参数 表示要应用的旋转度数 从 css3please com 我找到了一种使用 CSS 实现此功能的跨浏览器方法 box rotate moz trans

随机推荐

  • 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 感到困惑 将一种转换为另一种并不难 反之