当前位置: 首页 > article >正文

1.1Nodejs和浏览器中的二进制处理

Buffer

在 Node.js 中,Buffer 类用于处理二进制数据。由于 JavaScript 在浏览器环境中主要用于处理字符串和数字等类型的数据,对二进制数据的处理能力较弱,因此 Node.js 引入了 Buffer 类来弥补这一不足,特别是在处理文件系统操作、网络流等方面时。

Buffer 的基本概念

  • 固定大小:一旦创建,Buffer 实例的大小是固定的,不能调整。
  • 存储整数:每个 Buffer 实例都是一个包含 8 位无符号整数值(0 到 255)的数组。
  • 高效性:设计用来高效地存储和操作二进制数据。

Buffer不指定编码,默认转换时是 uft8编码

创建 Buffer

  1. 从字符串创建

    const buf = Buffer.from('hello', 'utf8');
  2. 从数组创建

    const buf = Buffer.from([0x62, 0x75, 0x66, 0x66, 0x65, 0x72]);
  3. 分配指定大小的 Buffer

     

    注意,直接使用 Buffer 构造函数或 .allocUnsafe() 分配内存时不初始化内存,可能包含敏感数据,建议使用 .alloc() 方法:

    const buf = Buffer.alloc(10); // 创建一个长度为 10,值全为 0 的 Buffer

操作 Buffer

  • 读写数据

     

    可以通过索引直接访问或修改 Buffer 中的数据:

    buf[0] = 0x62; // 修改第一个字节
    console.log(buf[0]); // 读取第一个字节
  • 转换

     

    转换为其他格式如字符串:

    const str = buf.toString('utf8');

其他常用方法

  • buf.length: 获取 Buffer 的字节长度。
  • buf.equals(otherBuffer): 检查两个 Buffer 是否相等。
  • buf.compare(otherBuffer): 比较两个 Buffer,类似于字符串比较。
  • buf.slice([start[, end]]): 返回一个新的 Buffer,它与原 Buffer 共享相同的内存区域,但偏移量不同。
  • buf.copy(targetBuffer[, targetStart[, sourceStart[, sourceEnd]]]): 将 Buffer 的一部分复制到另一个 Buffer。

注意事项

  • 处理 Buffer 时需要特别小心,因为它们可以直接访问内存,不正确的使用可能导致安全问题或内存泄漏。
  • 使用 Buffer 时应尽量避免使用未初始化的内存,即优先选择 Buffer.alloc() 而不是 Buffer.allocUnsafe()

Buffer 是 Node.js 中处理二进制数据的重要工具

浏览器中的二进制数据处理

在浏览器环境中,原生并不支持 Node.js 的 Buffer 类,因为 Buffer 是 Node.js 特有的用于处理二进制数据的类,主要用于服务器端开发。然而,在浏览器中,如果你需要处理二进制数据,可以使用 JavaScript 提供的几种内置对象和类型,例如 ArrayBufferTypedArray(如 Uint8Array)和 Blob 等。

  1. ArrayBuffer:一个固定长度的字节数组,不能直接操作其内容,而是通过视图(views)来读写数据。

  2. TypedArray:包括 Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, 和 Float64Array 等,提供了以特定格式访问 ArrayBuffer 数据的方法。

  3. DataView:提供了一个底层接口,用于访问 ArrayBuffer 中的数据,允许以不同的格式读写数据。

  4. Blob:代表不可变的、原始数据的类文件对象,基于输入的数据创建一个包含指定类型的二进制数据的对象。

  5. TextEncoder 和 TextDecoder:用于在字符串与 Uint8Array 之间进行转换。(我们在base64编码里使用过.6.6js对base64编码解码_js base64-CSDN博客)

ArrayBuffer

  • ArrayBuffer 本身是不可变的,意味着一旦创建,其大小不能更改。
  • 字节单位ArrayBuffer 的容量是以字节为单位的,因此当你创建一个 ArrayBuffer 时,需要指定它的大小(以字节为单位)。
  • 访问数据:直接使用 ArrayBuffer 并不容易,通常会通过视图(views),如 TypedArray 或者 DataView 来读取或写入其中的数据。
创建 ArrayBuffer

可以通过构造函数创建一个新的 ArrayBuffer

const buffer = new ArrayBuffer(16); // 创建一个包含16个字节的缓冲区
console.log(buffer.byteLength); // 输出: 16
TypedArray 视图

为了方便地操作 ArrayBuffer 中的数据,JavaScript 提供了多种类型的 TypedArray,每种类型对应不同的数值格式(例如整数、浮点数)和大小(例如8位、16位)。常用的 TypedArray 包括:

  • Int8Array
  • Uint8Array
  • Uint8ClampedArray
  • Int16Array
  • Uint16Array
  • Int32Array
  • Uint32Array
  • Float32Array
  • Float64Array
const buffer = new ArrayBuffer(16);
const uint8 = new Uint8Array(buffer); // 使用Uint8Array作为视图
uint8[0] = 42; // 设置第一个字节的值为42
console.log(uint8[0]); // 输出: 42
DataView 视图

除了 TypedArray,还可以使用 DataView 对象来读取和写入 ArrayBuffer 中的数据。DataView 提供了更加灵活的方法来处理不同大小和格式的数据,允许你在同一个 ArrayBuffer 上混合使用不同的数据类型。

const buffer = new ArrayBuffer(16);
const view = new DataView(buffer);
view.setUint8(0, 42); // 在偏移量为0的位置设置一个无符号8位整数
console.log(view.getUint8(0)); // 输出: 42

FileReader 读取文件并获取 ArrayBuffer

<!DOCTYPE html>
<html lang="zh">
<head><meta charset="UTF-8"><title>FileReader 读取 ArrayBuffer 示例</title>
</head>
<body><h2>请选择一个文件:</h2>
<input type="file" id="fileInput" /><pre id="output"></pre><script>document.getElementById('fileInput').addEventListener('change', function(event) {const file = event.target.files[0]; // 获取用户选择的第一个文件if (!file) {alert("请先选择一个文件!");return;}const reader = new FileReader();// 当读取完成时触发reader.onload = function(e) {const arrayBuffer = e.target.result; // result 是 ArrayBuffer 类型// 打印 ArrayBuffer 和它的长度console.log("ArrayBuffer:", arrayBuffer);console.log("字节长度:", arrayBuffer.byteLength);// 可选:将 ArrayBuffer 转换为 Uint8Array 查看前几个字节const uint8Array = new Uint8Array(arrayBuffer);const firstBytes = uint8Array.slice(0, 20); // 前20个字节document.getElementById('output').textContent ="前20个字节(十六进制):\n" +Array.prototype.map.call(firstBytes, b => ('00' + b.toString(16)).slice(-2)).join(' ');};// 开始读取文件为 ArrayBufferreader.readAsArrayBuffer(file);});
</script></body>
</html>

  • FileReader 是浏览器提供的用于异步读取文件内容的 API。
  • readAsArrayBuffer(file) 方法会将整个文件读取为一个 ArrayBuffer
  • reader.onload 回调中,e.target.result 就是读取到的 ArrayBuffer
  • 使用 Uint8Array 可以查看或操作原始二进制数据。
  • 这种方式非常适合用来解析各种二进制格式,如:
    • 图片文件(PNG/JPG)
    • PDF 文件
    • 音频/视频文件
    • 自定义二进制协议的数据包等

Node.js 中的 ArrayBuffer

在 Node.js 中也有 ArrayBuffer,它允许你处理通用的、固定长度的二进制数据缓冲区。ArrayBuffer 是 JavaScript 中的一个底层接口,用于表示一段连续的内存区域,这段内存不能直接操作,通常需要通过视图(如 TypedArray 或者 DataView)来访问和操作其中的数据。

在早期版本中,Node.js 和浏览器环境对于 ArrayBuffer 的支持存在一些差异,但是随着技术的发展,现在 Node.js 已经对 ArrayBuffer 提供了很好的支持,并且可以与浏览器环境兼容使用。这意味着你可以利用 ArrayBuffer 来处理文件、网络流等场景中的二进制数据。

在 Node.js 中使用 ArrayBuffer

const buffer = new ArrayBuffer(8); // 创建一个包含8个字节的缓冲区
console.log(buffer.byteLength); // 输出: 8


使用 TypedArray 访问 ArrayBuffer


要读取或写入 ArrayBuffer 中的数据,通常需要使用 TypedArray,例如 Uint8Array。

const buffer = new ArrayBuffer(8);
const view = new Uint8Array(buffer);// 写入数据
for (let i = 0; i < view.length; i++) {view[i] = i;
}// 读取数据
for (let i = 0; i < view.length; i++) {console.log(view[i]);
}


使用 DataView 访问 ArrayBuffer


如果你需要以不同的格式读取和写入数据(比如不同大小的整数或浮点数),可以使用 DataView。


const buffer = new ArrayBuffer(16);
const dataView = new DataView(buffer);// 写入不同类型的数据
dataView.setUint8(0, 255);
dataView.setFloat32(4, Math.PI);// 读取数据
console.log(dataView.getUint8(0)); // 输出: 255
console.log(dataView.getFloat32(4)); // 输出接近: Math.PI


这些例子展示了如何在 Node.js 中创建和操作 ArrayBuffer。无论你是处理文件 I/O、网络通信还是其他涉及二进制数据的操作,ArrayBuffer 都是一个非常强大的工具。此外,由于 Node.js 对 ArrayBuffer 的良好支持,使得从浏览器端到服务器端处理二进制数据变得更加统一和方便。

http://www.lryc.cn/news/2403131.html

相关文章:

  • 入门AJAX——XMLHttpRequest(Post)
  • Qt(part1)Qpushbutton,信号与槽,对象树,自定义信号与槽,lamda表达式。
  • 西北某省级联通公司:3D动环模块如何实现机房“一屏统管”?
  • 【WPF】从普通 ItemsControl 到支持筛选的 ItemsControl:深入掌握 CollectionViewSource 用法
  • Zookeeper 和 Kafka 版本与 JDK 要求
  • 3步布局关键词让流量更精准
  • 视觉分析在人员行为属性检测中的应用
  • 学习 React【Plan - June - Week 1】
  • 电子行业AI赋能软件开发经典案例——某金融软件公司
  • 【前端】js如何处理计算精度问题
  • 使用 Python 自动化 Word 文档样式复制与内容生成
  • Kafka 核心架构与消息模型深度解析(二)
  • 4G网络中频段的分配
  • SQL进阶之旅 Day 19:统计信息与优化器提示
  • 数据结构之LinkedList
  • 摆脱硬件依赖:SkyEye在轨道交通中的仿真应用
  • 使用变异系数增强 CFD 收敛标准
  • 解决获取视频第一帧黑屏问题
  • 物联网通信技术全景指南(2025)之如何挑选合适的物联网模块
  • 影楼精修-AI衣服祛褶皱算法解析
  • Day46 Python打卡训练营
  • 信号电压高,传输稳定性变强,但是传输速率下降?
  • linux安全加固(非常详细)
  • 关于事务的简介
  • qt控制台程序与qt窗口程序在读取数据库中文字段的差异!!巨坑
  • 动手学深度学习12.7. 参数服务器-笔记练习(PyTorch)
  • 告别数据泥沼,拥抱智能中枢:King’s四位一体重塑科研生产力
  • 智绅科技 —— 智慧养老 + 数字健康,构筑银发时代安全防护网
  • Code Composer Studio CCS 工程设置,如何设置h文件查找路径?
  • Qt生成日志与以及捕获崩溃文件(mingw64位,winDbg)————附带详细解说