Buffer浅析

JavaScript没有读取或操作二进制数据流的机制。Buffer类被引入作为Node.js API的一部分,使其可以在TCP流或文件系统操作等场景中处理二进制数据流。

在Node.js中,Buffer是用于处理二进制数据的类。它提供了一种在Node.js中处理二进制数据的方式,可以用于处理文件I/O、网络数据、加密算法等场景。Buffer类可以存储任意大小的二进制数据,并提供了一组方法用于对二进制数据进行操作,如读取、写入、拷贝等。

一、二进制数据

计算机存储和表示任何数据时,都会先将其转换为数字表示,再转换为二进制数。下面是一些常用数据类型的转换方式:

  • 整数:通过将整数转换为二进制表示。
  • 浮点数:使用IEEE 754标准将浮点数转换为二进制表示。
  • 字符:通过字符编码(如ASCII、UTF-8等)将字符转换为二进制表示。
  • 布尔值:通常使用1表示true,0表示false。
  • 对象和数组:通常使用JSON.stringify()方法来将引用数据类型转换为JSON格式的字符串,然后再通过一些方式(例如Blob对象)将字符串转换为二进制数据。
  • 图片:常见编码格式,如JPEG、PNG、GIF等,将其转换为二进制数据。这些编码格式会将图片的像素信息、颜色等转换为二进制数据。
  • 视频:常见编码格式,如H.264、MPEG-4等,将其转换为二进制数据。视频编码会对视频的每一帧进行压缩和编码,然后将其转换为二进制数据。
  • 音频:常见编码格式,如MP3、AAC等,将其转换为二进制数据。音频编码会对音频信号进行压缩和编码,然后将其转换为二进制数据。

二、Stream

在Node.js中,流(stream)就是一系列从A点到B点移动的数据。

完整的说,就是当有一个很大的数据需要传输、搬运时,不需要等待所有的数据都传输完成才开始进行下一步工作,而是会将巨型数据分割成小块(chunks)进行传输。

所以buffer的原始定义中所说的("streams of binary data... in the context of... file system")意思就是说二进制数据在文件系统中的传输。

三、Buffer

在每次数据传输的过程中,会存在一个数据量的问题。所以当数据到达的时间比数据处理的事件快的时候,我们处理数据就需要等待了;反之,如果处理数据的时间比到达的时间快,这一时刻仅仅到达了一小部分数据,那这一小部分数据需要等待剩下的数据填满,然后再送过去统一处理。

这个"等待区域"就是 Buffer。它是电脑上的一个很小的物理地址,一般在RAM中,在这里数据暂时的存储、等待,最后在流(stream)中,发送过去并处理。

等待状态

传输状态

下一次传输

"实例化"举例

1.公交站

可以把整个流(stream)和buffer的配合过程看作一个坐满人发车的公交站。

stream就是公交的行驶过程。

buffer就是公交站台。

乘客可能在不同的时间来到,人流量无法控制,但早到的乘客必须在站台等待,待当前这辆车能满员之后,才会发车;如果乘客到站发现车已经开走,只能在站台等待下一次满员的时候。

Node.js不能控制数据什么时候传输过来,传输速度,就好像公交车站无法控制人流量一样,它只能决定什么时候发送数据。如果时间还不到,那么Node.js就会把数据放入buffer---"等待区域"中,直到buffer满了之后把它们发送出去进行处理。

2.观看视频

当我们在线观看视频的时候,如果网速够快,数据流(stream)就可以足够快,可以让buffer迅速填满然后发送出去处理,然后处理下一个,再发送,再另一个,直到整个stream完成。

但当网络连接很慢的时候,数据流就会变慢,处理完一个buffer的内容后下一个buffer不能立即发送,视频就会暂停,出现等待转圈状态。

四、Buffer的一些基础API

在stream中,Node.js会自动帮你创建buffer之外,你可以创建自己的buffer并操作它。

csharp 复制代码
// 创建一个大小为10的空buffer
// 这个buffer只能承载10个字节的内容

const buf1 = Buffer.alloc(10);

// 根据内容直接创建buffer

const buf2 = Buffer.from("hello buffer");

创建了之后,就可以操作buffer了

scss 复制代码
// 检查下buffer的结构

buf1.toJSON()
// { type: 'Buffer', data: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] }
// 一个空的buffer

buf2.toJSON()
// { type: 'Buffer',data: [ 104, 101, 108, 108, 111, 32, 98, 117, 102, 102, 101, 114 ] }
// the toJSON() 方法可以将数据进行Unicode编码并展示
   
// 检查buffer的大小

buf1.length // 10

buf2.length //12 根据数据自动盛满并创建

//写入数据到buffer
buf1.write("Buffer really rocks!")

//解码buffer

buf1.toString() // 'Buffer rea'

//哦豁,因为buf1只能承载10个字节的内容,所有多处的东西会被截断

五、ArrayBuffer简介

ArrayBuffer是JavaScript中的内置对象,用于表示通用的、固定长度的原始二进制数据缓冲区。它提供了一种在JavaScript中处理二进制数据的方式,可以用于操作像音频、视频、图像和其他需要原始二进制数据的数据格式。

ArrayBuffer对象本身不能直接操作数据,但可以使用TypedArray视图或DataView对象来操作其内容。

TypeArray有九种如下类型

类型 描述
Int8Array 8位带符号整数数组
Uint8Array 8位无符号整数数组
Uint8ClampedArray 8位无符号整数数组(无法溢出)
Int16Array 16位带符号整数数组
Uint16Array 16位无符号整数数组
Int32Array 32位带符号整数数组
Uint32Array 32位无符号整数数组
Float32Array 32位浮点数数组
Float64Array 64位浮点数数组

node 中的 Buffer 就相当于是操作ArrayBuffer的一个视图(TypedArray中 的 Uint8Array ),因为 Buffer 就是通过继承 Uint8Array 实现的

ArrayBuffer的大小在创建时就被固定了,且不能直接修改大小,因此它更适合于固定大小的数据缓冲区。

"实例化"举例

ArrayBuffer就像是一块标本,TypedArray和DataView就像是显微镜操作台,你可以看(读)到这个 ArrayBuffer 但是你需要这些 TypedArray 或 DataView视图来操作这些数据。

六、Buffer、ArrayBuffer比较

Buffer ArrayBuffer
相同点 都可以进行读取、写入和操作二进制数据。
不同点 Node.js中用于处理二进制数据的对象 Web平台的标准,用于在浏览器中处理二进制数据
提供了更多的方法和功能,如将二进制数据转换为字符串、进行加密解密等 只能通过TypedArray视图或DataView对象来操作其内容,更偏向于底层的二进制数据操作

总的来说,ArrayBuffer是一段固定连续的二进制数据缓冲区,Buffer是用于NodeJS中用来操作ArrayBuffer的视图。

ArrBuffer转Buffer

使用Buffer.from

ini 复制代码
const buf = Buffer.from(arrayBuffer.buffer);

Buffer转ArrayBuffer

Buffer的实例维护了一个属性buffer,亦即ArrayBuffer

arduino 复制代码
const arrayBuffer = buf.buffer

七、附录

Buffer官方文档: Buffer | Node.js v8.17.0 Documentation (nodejs.org)

ArrayBuffer官方文档:ArrayBuffer - JavaScript | MDN (mozilla.org)

相关推荐
L耀早睡39 分钟前
mapreduce打包运行
大数据·前端·spark·mapreduce
HouGISer1 小时前
副业小程序YUERGS,从开发到变现
前端·小程序
outstanding木槿1 小时前
react中安装依赖时的问题 【集合】
前端·javascript·react.js·node.js
霸王蟹2 小时前
React中useState中更新是同步的还是异步的?
前端·javascript·笔记·学习·react.js·前端框架
霸王蟹2 小时前
React Hooks 必须在组件最顶层调用的原因解析
前端·javascript·笔记·学习·react.js
专注VB编程开发20年2 小时前
asp.net IHttpHandler 对分块传输编码的支持,IIs web服务器后端技术
服务器·前端·asp.net
爱分享的程序员2 小时前
全栈项目搭建指南:Nuxt.js + Node.js + MongoDB
前端
隐含3 小时前
webpack打包,把png,jpg等文件按照在src目录结构下的存储方式打包出来。解决同一命名的图片资源在打包之后,重复命名的图片就剩下一个图片了。
前端·webpack·node.js
lightYouUp3 小时前
windows系统中下载好node无法使用npm
前端·npm·node.js
Dontla3 小时前
npm cross-env工具包介绍(跨平台环境变量设置工具)
前端·npm·node.js