深入浅出JavaScript中的ArrayBuffer:二进制数据的“瑞士军刀”
深入浅出JavaScript中的ArrayBuffer:二进制数据的“瑞士军刀”
在JavaScript中,我们经常需要处理文本、数组、对象等数据类型。但当我们需要处理文件上传、图像处理、网络通信等场景时,单纯依赖字符串或数组就显得力不从心了。这时,ArrayBuffer便成为了一个不可或缺的工具。它像一把“瑞士军刀”,让我们能够直接操作底层的二进制数据。
本文将从概念、操作方式和实际应用三个维度,带你深入浅出地了解ArrayBuffer的魅力。
一、什么是ArrayBuffer?
ArrayBuffer 是 JavaScript 中用于表示原始二进制数据缓冲区的对象。它本质上是一块固定长度的连续内存区域,存储的是字节数据(byte),而不是具体的数值或字符串。你可以把它想象成一块“画布”,而这块画布上可以绘制不同类型的数据(如整数、浮点数、字符串等)。
核心特点:
- 固定长度:创建后长度不可变,若需调整大小,必须重新分配内存并复制数据。
- 原始二进制数据:存储的是字节(0~255),没有类型信息。
- 不可直接操作:需要通过 TypedArray 或 DataView 来访问和修改数据。
二、如何创建ArrayBuffer?
创建ArrayBuffer非常简单,只需指定字节数即可:
const buffer = new ArrayBuffer(16); // 创建一个16字节的缓冲区
console.log(buffer.byteLength); // 输出: 16
此时,buffer
是一个空的字节容器,存储了16个字节的数据(每个字节为8位)。虽然它已经存在,但我们还不能直接读写其中的内容,必须通过视图(TypedArray或DataView)来操作。
三、操作ArrayBuffer的两种方式
1. TypedArray:类型化数组
TypedArray是操作ArrayBuffer的“标准工具”,它允许我们以特定的数据类型(如整数、浮点数)来读取和写入数据。常见的TypedArray类型包括:
Int8Array
:8位有符号整数Uint8Array
:8位无符号整数Int16Array
:16位有符号整数Float32Array
:32位浮点数Float64Array
:64位浮点数
示例:使用TypedArray操作ArrayBuffer
// 创建一个8字节的ArrayBuffer
const buffer = new ArrayBuffer(8);// 创建一个Uint8Array视图(8位无符号整数)
const uint8Array = new Uint8Array(buffer);// 写入数据
uint8Array[0] = 10;
uint8Array[1] = 20;
uint8Array[2] = 30;console.log(uint8Array); // 输出: Uint8Array(8) [10, 20, 30, 0, 0, 0, 0, 0]
console.log(buffer); // 输出: ArrayBuffer(8) { byteLength: 8 }
关键点:
- 每个TypedArray视图的长度取决于ArrayBuffer的大小和数据类型的字节数。例如,一个16字节的ArrayBuffer,如果用
Int32Array
(4字节/元素)视图,长度为4。 - TypedArray提供了
set
、subarray
等方法,但不具备splice
、concat
等数组方法。
2. DataView:灵活的访问方式
DataView是操作ArrayBuffer的“瑞士军刀”,它允许我们以任意偏移量和数据类型读写数据,甚至可以指定字节序(大端或小端)。它特别适合处理混合格式的数据(如网络协议包)。
示例:使用DataView操作ArrayBuffer
const buffer = new ArrayBuffer(8);
const dataView = new DataView(buffer);// 写入数据(指定字节序)
dataView.setInt8(0, 10); // 从偏移0开始,写入8位有符号整数
dataView.setUint16(1, 256, true); // 从偏移1开始,写入16位无符号整数(小端序)
dataView.setFloat32(3, 3.14, false); // 从偏移3开始,写入32位浮点数(大端序)// 读取数据
console.log(dataView.getInt8(0)); // 输出: 10
console.log(dataView.getUint16(1, true)); // 输出: 256
console.log(dataView.getFloat32(3, false)); // 输出: 3.14
关键点:
- DataView的灵活性体现在可以动态指定偏移量和字节序。
- 对于需要处理多种数据类型或跨平台数据的场景(如网络协议解析),DataView是更优选择。
四、ArrayBuffer的实际应用场景
1. 文件上传与处理
当用户上传图片、音频等文件时,可以通过FileReader
读取为ArrayBuffer,再用TypedArray或DataView解析内容。
const fileInput = document.querySelector('input[type="file"]');
const reader = new FileReader();reader.onload = (e) => {const buffer = e.target.result; // 获取ArrayBufferconst dataView = new DataView(buffer);// 处理文件内容...
};reader.readAsArrayBuffer(fileInput.files[0]);
2. 图像处理
以PNG文件为例,其文件头前8字节包含特定签名(0x89 0x50 0x4E 0x47 0x0D 0x0A 0x1A 0x0A
)。我们可以用ArrayBuffer验证文件合法性:
fileInput.onchange = e => {const file = e.target.files[0];const reader = new FileReader();reader.onload = function() {const buffer = this.result;const header = new Uint8Array(buffer, 0, 8); // 读取前8字节// 校验PNG文件签名if (header[0] === 0x89 && header[1] === 0x50) {console.log("合法PNG文件");}};reader.readAsArrayBuffer(file);
};
3. WebSocket二进制通信
在WebSocket通信中,可以通过ArrayBuffer高效传输二进制数据:
const socket = new WebSocket('ws://example.com');
socket.binaryType = 'arraybuffer'; // 设置接收类型为ArrayBuffersocket.onmessage = (e) => {const buffer = e.data; // 接收ArrayBufferconst dataView = new DataView(buffer);// 解析数据...
};
五、注意事项与最佳实践
-
内存分配问题
ArrayBuffer的大小固定,若分配过大可能导致内存不足。建议根据实际需求合理规划内存,并及时释放不再使用的ArrayBuffer。 -
字节序(Endianness)
不同平台对多字节数据的存储顺序不同(大端序 vs 小端序)。在跨平台数据处理中,务必通过DataView明确指定字节序。 -
性能优化
频繁操作ArrayBuffer时,避免重复创建视图。尽量复用视图对象,并通过subarray
或set
方法操作数据。 -
与普通数组的区别
ArrayBuffer是二进制数据的“容器”,而普通数组存储的是JavaScript值(如数字、字符串)。两者在内存效率和操作方式上有显著差异。
六、总结
ArrayBuffer是JavaScript处理二进制数据的核心工具,它通过TypedArray和DataView提供了灵活且高效的底层操作能力。无论是处理文件上传、图像解析,还是实现网络通信,ArrayBuffer都能发挥重要作用。掌握它的原理和使用方法,将大大提升你在Web开发中处理复杂数据的能力。
如果你正在开发需要高性能数据处理的应用(如图像编辑器、音视频播放器、实时通信工具),ArrayBuffer绝对是你需要深入了解和掌握的利器。现在,不妨动手尝试一些简单的例子,感受它带来的“二进制魔法”吧!
延伸阅读:
- MDN文档:ArrayBuffer
- MDN文档:TypedArray
- MDN文档:DataView
希望这篇文章能帮你更好地理解和使用ArrayBuffer!如果还有疑问,欢迎在评论区留言交流。
相关文章:
深入浅出JavaScript中的ArrayBuffer:二进制数据的“瑞士军刀”
深入浅出JavaScript中的ArrayBuffer:二进制数据的“瑞士军刀” 在JavaScript中,我们经常需要处理文本、数组、对象等数据类型。但当我们需要处理文件上传、图像处理、网络通信等场景时,单纯依赖字符串或数组就显得力不从心了。这时ÿ…...

理想汽车5月交付40856辆,同比增长16.7%
6月1日,理想汽车官方宣布,5月交付新车40856辆,同比增长16.7%。截至2025年5月31日,理想汽车历史累计交付量为1301531辆。 官方表示,理想L系列智能焕新版在5月正式发布,全系产品力有显著的提升,每…...
Linux中INADDR_ANY详解
在Linux网络编程中,INADDR_ANY 是一个特殊的IPv4地址常量(定义在 <netinet/in.h> 头文件中),用于表示绑定到所有可用网络接口的地址。它是服务器程序中的常见用法,允许套接字监听所有本地IP地址上的连接请求。 关…...

运行vue项目报错 errors and 0 warnings potentially fixable with the `--fix` option.
报错 找到package.json文件 找到这个修改成 "lint": "eslint --fix --ext .js,.vue src" 为elsint有配置结尾换行符,最后运行:npm run lint --fix...
java+webstock
maven依赖 <dependency><groupId>org.java-websocket</groupId><artifactId>Java-WebSocket</artifactId><version>1.3.5</version></dependency><dependency><groupId>org.apache.tomcat.websocket</groupId&…...
STL 2迭代器
文章目录 1.迭代器2.输入迭代器3.输出迭代器1.插入迭代器 4.前向迭代器5.双向迭代器6.随机访问迭代器7.不同容器返回的迭代器类型1.输入 / 输出迭代器2.前向迭代器3.双向迭代器4.随机访问迭代器5.特殊迭代器适配器6.为什么 unordered_set 只提供前向迭代器? 1.迭代器…...
CppCon 2015 学习:Simple, Extensible Pattern Matching in C++14
什么是 Pattern Matching(模式匹配) ❝ 模式匹配就是一种“描述式”的写法,不需要你手动判断、提取数据,而是直接描述你希望的数据结构是什么样子,系统自动判断并提取。❞ 你给的定义拆解: ✴ Instead of …...

智警杯备赛--excel模块
数据透视与图表制作 创建步骤 创建 1.在Excel的插入或者数据标签页下找到数据透视表的按钮 2.将数据放进“请选择单元格区域“中,点击确定 这是最终结果,但是由于环境启不了,这里用的是自己的excel,真实的环境中的excel根据实训…...
uniapp获取当前位置和经纬度信息
1.1. 获取当前位置和经纬度信息(需要配置高的SDK) 调用uni-app官方API中的uni.chooseLocation(),即打开地图选择位置。 <button click"getAddress">获取定位</button> const getAddress () > {uni.chooseLocatio…...

【多线程初阶】单例模式 指令重排序问题
文章目录 1.单例模式1)饿汉模式2)懒汉模式①.单线程版本②.多线程版本 2.分析单例模式里的线程安全问题1)饿汉模式2)懒汉模式懒汉模式是如何出现线程安全问题的 3.解决问题进一步优化加锁导致的执行效率优化预防内存可见性问题 4.解决指令重排序问题 1.单例模式 单例模式确保某…...

基于Python的气象数据分析及可视化研究
目录 一.🦁前言二.🦁开源代码与组件使用情况说明三.🦁核心功能1. ✅算法设计2. ✅PyEcharts库3. ✅Flask框架4. ✅爬虫5. ✅部署项目 四.🦁演示效果1. 管理员模块1.1 用户管理 2. 用户模块2.1 登录系统2.2 查看实时数据2.3 查看天…...

Pandas 可视化集成:数据科学家的高效绘图指南
为什么选择 Pandas 进行数据可视化? 在数据科学和分析领域,可视化是理解数据、发现模式和传达见解的关键步骤。Python 生态系统提供了多种可视化工具,如 Matplotlib、Seaborn、Plotly 等,但 Pandas 内置的可视化功能因其与数据结…...

新版NANO下载烧录过程
一、序言 搭建 Jetson 系列产品烧录系统的环境需要在电脑主机上安装 Ubuntu 系统。此处使用 18.04 LTS。 二、环境搭建 1、安装库 $ sudo apt-get install qemu-user-static$ sudo apt-get install python 搭建环境的过程需要这个应用库来将某些 NVIDIA 软件组件安装到 Je…...
Vue 实例的数据对象详解
Vue 实例的数据对象详解 在 Vue 中,数据对象是响应式系统的核心,也是组件状态的载体。理解数据对象的原理和使用方式是成为 Vue 专家的关键一步。我将从多个维度深入剖析 Vue 实例的数据对象。 一、数据对象的定义方式 1. Options API 中的定义 在 Options API 中,使用 …...

Axure Rp 11 安装、汉化、授权
Axure Rp 11 安装、汉化、授权 1、前言2、汉化2.1、汉化文件下载2.2、windows汉化流程2.3、 macOs汉化流程 3、授权 1、前言 Axure Rp 11官方下载链接:https://www.axure.com/downloadthanks 2、汉化 2.1、汉化文件下载 链接: https://pan.baidu.com/s/18Clf…...

中科院1区顶刊|IF14+:多组学MR联合单细胞时空分析,锁定心血管代谢疾病的免疫治疗新靶点
中科院1区顶刊|IF14:多组学MR联合单细胞时空分析,锁定心血管代谢疾病的免疫治疗新靶点 当下,免疫与代谢性疾病的关联研究已成为生命科学领域的前沿热点。随着研究的深入,我们愈发清晰地认识到免疫系统与代谢系统之间存在着极为复…...
GB/T 43887-2024 核级柔性石墨板材检测
核级柔性石墨板材是指以可膨胀石墨为原料、未经改性和增强、用于核工业的核级柔性石墨板材。 GB/T 43887-2024核级柔性石墨板材检测检测指标: 测试项目 测试标准 外观 GB/T 43887 尺寸偏差 GB/T 43887 化学成分 GB/T 43887 密度偏差 GB/T 43887 拉伸强度…...
ffmpeg(三):处理原始数据命令
FFmpeg 可以直接处理原始音频和视频数据(Raw PCM、YUV 等),常见场景包括: 将原始 YUV 图像编码为 H.264 视频将 PCM 音频编码为 AAC 或 MP3对原始音视频数据进行封装(如封装为 MP4、TS) 处理原始 YUV 视频…...
标注工具核心架构分析——主窗口的图像显示
🏗️ 标注工具核心架构分析 📋 系统概述 主要有两个核心类,采用经典的 Scene-View 架构模式: 🎯 核心类结构 1. AnnotationScene (QGraphicsScene子类) 主要负责标注场景的管理和交互 🔧 关键函数&…...

作为点的对象CenterNet论文阅读
摘要 检测器将图像中的物体表示为轴对齐的边界框。大多数成功的目标检测方法都会枚举几乎完整的潜在目标位置列表,并对每一个位置进行分类。这种做法既浪费又低效,并且需要额外的后处理。在本文中,我们采取了不同的方法。我们将物体建模为单…...
基于Java项目的Karate API测试
Karate 实现了可以只编写Feature 文件进行测试,但是对于熟悉Java语言的开发或是测试人员,可以通过编程方式集成 Karate 丰富的自动化和数据断言功能。 本篇快速介绍在Java Maven项目中编写和运行测试的示例。 创建Maven项目 最简单的创建项目的方式就是创建一个目录,里面…...
自定义线程池1.2
自定义线程池 1.2 1. 简介 上次我们实现了 1.1 版本,将线程池中的线程数量交给使用者决定,并且将线程的创建延迟到任务提交的时候,在本文中我们将对这个版本进行如下的优化: 在新建线程时交给线程一个任务。让线程在某种情况下…...
Spring事务传播机制有哪些?
导语: Spring事务传播机制是后端面试中的必考知识点,特别容易出现在“项目细节挖掘”阶段。面试官通过它来判断你是否真正理解事务控制的本质与异常传播机制。本文将从实战与源码角度出发,全面剖析Spring事务传播机制,帮助你答得有…...

使用ch340继电器完成随机断电测试
前言 如图所示是市面上常见的OTA压测继电器,通过ch340串口模块完成对继电器的分路控制,这里我编写了一个脚本方便对4路继电器的控制,可以设置开启时间,关闭时间,复位等功能 软件界面 在设备管理器查看串口号后&…...

基于谷歌ADK的 智能产品推荐系统(2): 模块功能详解
在我的上一篇博客:基于谷歌ADK的 智能产品推荐系统(1): 功能简介-CSDN博客 中我们介绍了个性化购物 Agent 项目,该项目展示了一个强大的框架,旨在模拟和实现在线购物环境中的智能导购。它不仅仅是一个简单的聊天机器人,更是一个集…...

VSCode 没有添加Windows右键菜单
关键字:VSCode;Windows右键菜单;注册表。 文章目录 前言一、工程环境二、配置流程1.右键文件打开2.右键文件夹打开3.右键空白处打开文件夹 三、测试总结 前言 安装 VSCode 时没有注意,实际使用的时候发现 VSCode 在 Windows 菜单栏…...

vxe-table vue 表格复选框多选数据,实现快捷键 Shift 批量选择功能
vxe-table vue 表格复选框多选数据,实现快捷键 Shift 批量选择功能 查看官网:https://vxetable.cn 效果 代码 通过 checkbox-config.isShift 启用批量选中,启用后按住快捷键和鼠标批量选取 <template><div><vxe-grid v-bind"gri…...

Android Framework预装traceroute执行文件到system/bin下
文章目录 Android SDK中寻找traceroute代码内置traceroute到SDK中traceroute参数说明-I 参数(使用 ICMP Echo 请求)-T 参数(使用 TCP SYN 包) 相关文章 Android SDK中寻找traceroute代码 设备使用的是Android 11,在/s…...

生信服务器 | 做生信为什么推荐使用Linux服务器?
原文链接:生信服务器 | 做生信为什么推荐使用Linux服务器? 一、 做生信为什么推荐使用服务器? 大家好,我是小杜。在做生信分析的同学,或是将接触学习生信分析的同学,<font style"color:rgb(53, 1…...

react-pdf(pdfjs-dist)如何兼容老浏览器(chrome 49)
之前都是使用react-pdf来渲染pdf文件,这次有个需求是要兼容xp环境,xp上chrome最高支持到49,虽然说iframe或者embed都可以实现预览pdf,但为了后续的定制化需求,还是需要使用js库来渲染。 chrome 49测试环境 能用的测试…...