news 2026/10/23 11:05:09

Buffer 新手入门【Node.js】

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Buffer 新手入门【Node.js】

目录

  • Node.js Buffer 新手入门
  • 一、Buffer 是什么?
  • 二、为什么 Node.js 需要 Buffer?
  • 三、可以把 Buffer 理解成什么?
  • 四、Buffer 的几个重要特点
    • 1. Buffer 的长度固定
    • 2. Buffer 每一个元素占 1 个字节
    • 3. Buffer 可以直接操作二进制数据
  • 五、Buffer 的创建方式
  • 六、Buffer.alloc()
    • 1. 创建指定长度的 Buffer
    • 2. 为什么是 00?
  • 七、Buffer.allocUnsafe()
    • 为什么叫 Unsafe?
  • 八、Buffer.from()
    • 1. 根据字符串创建
  • 九、ASCII 和 Buffer
  • 十、Buffer.toString()
  • 十一、字符串 → Buffer → 字符串
  • 十二、Buffer 可以使用 [] 访问
  • 十三、修改 Buffer
  • 十四、Buffer 中的数字为什么最大是 255?
  • 十五、超过 255 会发生什么?
  • 十六、为什么 buf[0].toString(2) 可以看到二进制?
    • toString(2) / toString(10) / toString(16)
  • 十七、为什么 Buffer 输出经常是十六进制?
  • 十八、中文为什么占 3 个字节?
  • 十九、字符数量和字节数量一定一样吗?
  • 二十、Buffer.length 到底表示什么?
  • 二十一、Buffer 常用属性和方法
  • 二十二、Buffer.concat()
  • 二十三、Buffer.slice() / subarray()
  • 二十四、Buffer 和 Array 有什么区别?
      • Array
      • Buffer
  • 二十五、Buffer 在 Node.js 中到底用在哪里?
    • 1. 文件
    • 2. 网络
    • 3. HTTP
    • 4. 图片、音频、视频
  • 二十六、Buffer 和 Stream 有什么关系?
  • 二十七、Buffer、二进制、编码三者是什么关系?
  • 二十八、最重要的几个概念一定要分清
      • 字符
      • 字节 Byte
      • 二进制
      • 编码
      • 十六进制
  • 二十九、一张图理解 Buffer
  • 三十、新手现阶段记住这几个就够了

Node.js Buffer 新手入门

一、Buffer 是什么?

在 Node.js 中,经常会看到:Buffer;很多刚接触 Node.js 的人第一次看到它会觉得:Buffer到底是什么?为什么 Node.js 要专门设计一个Buffer?

其实可以先把它简单理解成:

Buffer 就是一块专门用来存放二进制数据的内存空间。

例如:

constbuf=Buffer.from('hello');console.log(buf);

输出:

<Buffer 68 65 6c 6c 6f>

这里的:

68 65 6c 6c 6f

并不是普通的字符串,而是hello在 UTF-8 编码下对应的二进制字节。


二、为什么 Node.js 需要 Buffer?

JavaScript 最开始主要是运行在浏览器里的。

浏览器中的 JavaScript 经常处理:

字符串 数字 对象 数组 DOM

但是 Node.js 不一样。

Node.js 经常需要直接处理计算机底层的数据,例如:

文件 TCP 网络数据 HTTP 请求 图片 音频 视频 压缩文件 加密数据 WebSocket 数据

这些数据本质上都是:

一串二进制数据,也就是一串 0 和 1。

例如:

01001000 01100101 01101100 01101100 01101111

如果我们全部使用普通 JavaScript 字符串来处理,会比较麻烦。

所以 Node.js 提供了:

Buffer

专门用于处理二进制数据。


三、可以把 Buffer 理解成什么?

可以把 Buffer 想象成一个:

固定大小的字节数组。

例如:

constbuf=Buffer.alloc(5);

可以理解成:

┌────┬────┬────┬────┬────┐ │ 00 │ 00 │ 00 │ 00 │ 00 │ └────┴────┴────┴────┴────┘ 1B 1B 1B 1B 1B

每一个位置:

1 byte = 8 bit

所以一个 Buffer 的 5 个位置:

5 byte

也就是:

40 bit

四、Buffer 的几个重要特点

1. Buffer 的长度固定

例如:

constbuf=Buffer.alloc(5);console.log(buf.length);

输出:

5

创建的时候指定了:

5 byte

这个 Buffer 的长度就是固定的。


2. Buffer 每一个元素占 1 个字节

例如:

constbuf=Buffer.from([10,20,30]);console.log(buf);

可以理解成:

┌────┬────┬────┐ │ 10 │ 20 │ 30 │ └────┴────┴────┘ 1B 1B 1B

所以:

buf.length

得到:

3

3. Buffer 可以直接操作二进制数据

例如:

constbuf=Buffer.from([65,66,67]);console.log(buf);

得到:

<Buffer 41 42 43>

转换成字符串:

console.log(buf.toString());

得到:

ABC

因为:

65 → A 66 → B 67 → C

五、Buffer 的创建方式

Node.js 中最常见的创建 Buffer 的方法主要有:

Buffer.alloc() Buffer.allocUnsafe() Buffer.from()

六、Buffer.alloc()

1. 创建指定长度的 Buffer

constbuf1=Buffer.alloc(10);console.log(buf1);

输出:

<Buffer 00 00 00 00 00 00 00 00 00 00>

也就是创建:

10 byte

的 Buffer。

默认全部初始化为:

00

2. 为什么是 00?

因为:

Buffer.alloc()

会对新分配的内存进行初始化。

所以:

Buffer.alloc(5)

相当于:

00 00 00 00 00

这样更加安全,因为你拿到的内存不会直接暴露之前的数据。


七、Buffer.allocUnsafe()

还可以:

constbuf2=Buffer.allocUnsafe(10);console.log(buf2);

它同样创建:

10 byte

的 Buffer。

但是:

allocUnsafe()

不会像alloc()一样保证把内存全部清零。

因此理论上可能看到之前内存中遗留的数据。

例如可能出现:

<Buffer 00 7a 31 9f ...>

具体内容是不确定的。


为什么叫 Unsafe?

因为:

Unsafe = 不安全

它的主要特点是:

速度更快 但是不会保证初始化为 0

所以:

Buffer.alloc()

更适合普通场景。

而:

Buffer.allocUnsafe()

通常用于你非常清楚自己在做什么,并且会立即覆盖全部数据的场景。

例如:

constbuf=Buffer.allocUnsafe(10);buf.fill(0);console.log(buf);

八、Buffer.from()

Buffer.from()是我们平时非常常用的方法。

它可以根据不同的数据创建 Buffer。


1. 根据字符串创建

constbuf3=Buffer.from('hello');console.log(buf3);

输出:

<Buffer 68 65 6c 6c 6f>

为什么是这些数字?

因为字符串:

hello

经过 UTF-8 编码以后:

h → 68 e → 65 l → 6c l → 6c o → 6f

这里显示的是:

十六进制

所以:

68 65 6c 6c 6f

对应:

hello

九、ASCII 和 Buffer

Buffer.from([105,108,111,118,101,121,111,117])

就是一个很好的例子。

这些数字按照 ASCII:

105 → i 108 → l 111 → o 118 → v 101 → e 121 → y 111 → o 117 → u

所以:

105 108 111 118 101 121 111 117

就是:

i love you

创建 Buffer:

constbuf=Buffer.from([105,108,111,118,101,121,111,117]);console.log(buf.toString());

输出:

iloveyou

这里要注意:

Buffer 本身并不知道“这是 ASCII 还是 UTF-8 字符”。它本质上只是保存字节。

编码决定了这些字节应该如何解释。


十、Buffer.toString()

Buffer 和字符串之间可以相互转换。

例如:

constbuf=Buffer.from('hello');console.log(buf);

得到:

<Buffer 68 65 6c 6c 6f>

转换成字符串:

console.log(buf.toString());

得到:

hello

默认使用:

utf8

也可以明确写:

console.log(buf.toString('utf8'));

十一、字符串 → Buffer → 字符串

这是非常重要的一条链路:

字符串 ↓ 编码 ↓ Buffer ↓ 解码 ↓ 字符串

例如:

conststr='hello';constbuf=Buffer.from(str);console.log(buf);constresult=buf.toString('utf8');console.log(result);

结果:

hello → Buffer → hello

可以理解为:

'hello' ↓ UTF-8 编码 Buffer ↓ UTF-8 解码 'hello'

十二、Buffer 可以使用 [] 访问

Buffer 和数组很像。

例如:

constbuf4=Buffer.from([105,108,111,118,101,121,111,117]);

可以通过下标读取:

console.log(buf4[0]);

得到:

105

再比如:

console.log(buf4[1]);

得到:

108

十三、修改 Buffer

Buffer 也可以通过下标修改。

例如:

constbuf=Buffer.from('hello');console.log(buf.toString());

得到:

hello

修改:

buf[0]=72;

再转换:

console.log(buf.toString());

得到:

Hello

因为:

72 → H

十四、Buffer 中的数字为什么最大是 255?

这是 Buffer 非常重要的一个知识点。

一个字节:

1 byte = 8 bit

8 个 bit 最多能够表示:

11111111

转换成十进制:

255

所以一个 Buffer 元素的正常范围是:

0 ~ 255

也就是:

0<=buf[i]<=255

十五、超过 255 会发生什么?

例如:

constbuf=Buffer.from('hello');buf[0]=361;

361 的二进制:

101101001

Buffer 一个字节只能保存 8 bit。

因此最终只保留低 8 位:

01101001

转换成十进制:

105

105 对应 ASCII:

e

所以:

console.log(buf[0]);

得到:

105

而:

console.log(buf.toString());

会变成:

eello

可以记住:

Buffer 的一个元素只能保存一个字节,也就是 0~255。


十六、为什么 buf[0].toString(2) 可以看到二进制?

例如:

constbuf=Buffer.from('hello');console.log(buf[0]);

得到:

104

因为:

h → 104

然后:

console.log(buf[0].toString(2));

得到:

1101000

如果希望按照一个完整字节显示,可以补成:

01101000

这里的:

toString(2)

意思是:

把数字转换成二进制字符串。


toString(2) / toString(10) / toString(16)

例如:

constnum=104;console.log(num.toString(2));console.log(num.toString(10));console.log(num.toString(16));

分别是:

1101000 104 68

也就是:

二进制 → 2 十进制 → 10 十六进制 → 16

十七、为什么 Buffer 输出经常是十六进制?

例如:

constbuf=Buffer.from('hello');console.log(buf);

Node.js 输出:

<Buffer 68 65 6c 6c 6f>

这里:

68 65 6c 6c 6f

是:

十六进制表示法

而不是十进制。

Buffer 存的是字节,而 Node.js 为了让二进制数据更方便人类阅读,默认使用十六进制来展示这些字节。

例如:

十进制 104 = 十六进制 68

所以:

h ↓ ASCII / UTF-8 ↓ 十进制 104 ↓ 十六进制 68 ↓ Buffer 中显示 68

十八、中文为什么占 3 个字节?

例如:

constbuf=Buffer.from('你好');console.log(buf);

可能得到:

<Buffer e4 bd a0 e5 a5 bd>

然后:

console.log(buf.length);

得到:

6

但是:

你好

明明只有:

2 个字符

为什么 Buffer 长度是:

6

原因是:

JavaScript 字符串中的“字符数量”和 UTF-8 编码后的“字节数量”不是一回事。

在 UTF-8 中:

你 → 3 byte 好 → 3 byte

所以:

你 + 好 ↓ 3 + 3 ↓ 6 byte

十九、字符数量和字节数量一定一样吗?

不一定。

例如英文:

constbuf=Buffer.from('hello');console.log(buf.length);

得到:

5

因为:

h → 1 byte e → 1 byte l → 1 byte l → 1 byte o → 1 byte

所以:

5 个字符 = 5 个字节

但是中文:

constbuf=Buffer.from('你好');console.log(buf.length);

得到:

6

所以:

2 个字符 ≠ 6 个字节

这就是:

字符 ≠ 字节

一定要把这两个概念分开。


二十、Buffer.length 到底表示什么?

例如:

constbuf=Buffer.from('你好');console.log(buf.length);

得到:

6

这里的length表示:

Buffer 中有多少个字节。

不是:

有多少个汉字

也不是:

有多少个字符

而是:

多少 byte

二十一、Buffer 常用属性和方法

实际开发中最常见的可以先记住这些:

API作用
Buffer.alloc(size)创建指定大小并初始化为 0 的 Buffer
Buffer.allocUnsafe(size)创建指定大小但不保证初始化的 Buffer
Buffer.from(data)根据数据创建 Buffer
buf.lengthBuffer 的字节长度
buf[index]读取指定位置的字节
buf[index] = value修改指定位置的字节
buf.toString()Buffer 转字符串
buf.toString('hex')转成十六进制字符串
buf.toString('base64')转成 Base64
buf.slice()获取 Buffer 的一部分
buf.subarray()获取 Buffer 的一部分
Buffer.concat()拼接多个 Buffer
buf.equals()判断两个 Buffer 是否相同
buf.includes()判断 Buffer 是否包含某个数据
buf.indexOf()查找数据位置
buf.fill()填充 Buffer

二十二、Buffer.concat()

Buffer 还可以进行拼接。

例如:

constbuf1=Buffer.from('hello ');constbuf2=Buffer.from('world');constresult=Buffer.concat([buf1,buf2]);console.log(result.toString());

得到:

hello world

可以理解成:

Buffer 1 hello + Buffer 2 world ↓ Buffer.concat() ↓ hello world

这个在处理网络数据流的时候非常常见。


二十三、Buffer.slice() / subarray()

例如:

constbuf=Buffer.from('hello');constresult=buf.subarray(0,2);console.log(result.toString());

得到:

he

可以理解成:

h e l l o ↑ ↑ 取 0 ~ 2

注意:

subarray(0,2)

结束位置2不包含。

和数组的切片规则比较类似:

[start, end)

二十四、Buffer 和 Array 有什么区别?

Buffer 看起来很像数组:

constarr=[65,66,67];constbuf=Buffer.from([65,66,67]);

都可以:

arr[0]buf[0]

但是它们的定位完全不同。

Array

普通 JavaScript 数组:

constarr=[65,66,67];

主要用于:

存储和操作 JavaScript 数据

数组里面甚至可以放:

[1,'hello',true,{},null]

Buffer

Buffer:

constbuf=Buffer.from([65,66,67]);

主要用于:

存储和处理二进制字节数据

每一个元素本质上都是:

一个字节

范围:

0 ~ 255

所以可以简单记:

Array ↓ JavaScript 数据容器 Buffer ↓ 二进制数据容器

二十五、Buffer 在 Node.js 中到底用在哪里?

Buffer 在 Node.js 中非常重要。

例如:

1. 文件

读取文件:

importfsfrom'node:fs';constdata=fs.readFileSync('./test.png');console.log(data);

读取二进制文件时,就可能得到 Buffer。

例如:

图片 ↓ Buffer ↓ 二进制数据

2. 网络

例如 TCP:

客户端 ↓ 二进制数据 ↓ Node.js ↓ Buffer

Node.js 网络 API 经常会使用 Buffer。


3. HTTP

请求/响应的数据底层也可能以字节流的形式处理。

例如:

HTTP 数据 ↓ 字节 ↓ Buffer ↓ 字符串 / JSON / 文件

4. 图片、音频、视频

例如:

jpg png mp3 mp4 zip pdf

这些文件本质上都是:

二进制数据。

因此 Buffer 非常适合处理。


二十六、Buffer 和 Stream 有什么关系?

这是学习 Node.js 时非常重要的一组概念。

假设你要读取一个:

10GB

的视频文件。

如果一次性读取:

10GB ↓ 全部放进内存

可能会造成很大的内存压力。

所以 Node.js 经常使用:

Stream(流)

把数据分成一小块一小块处理。

例如:

大文件 ↓ ┌──────┐ │ chunk│ → Buffer ├──────┤ │ chunk│ → Buffer ├──────┤ │ chunk│ → Buffer ├──────┤ │ chunk│ → Buffer └──────┘

也就是说:

Stream 负责“流式传输”,Buffer 经常负责“承载每一小块二进制数据”。

这个关系非常重要。


二十七、Buffer、二进制、编码三者是什么关系?

可以把它们理解成:

字符串 ↓ 编码(UTF-8) ↓ 字节 ↓ Buffer

反过来:

Buffer ↓ 字节 ↓ 解码(UTF-8) ↓ 字符串

例如:

conststr='你好';constbuf=Buffer.from(str,'utf8');console.log(buf);console.log(buf.toString('utf8'));

整个过程:

'你好' ↓ UTF-8 编码 ↓ e4 bd a0 e5 a5 bd ↓ Buffer ↓ UTF-8 解码 ↓ '你好'

二十八、最重要的几个概念一定要分清

学习 Buffer 的时候,最容易混淆的是:

字符 字节 二进制 编码 十进制 十六进制

可以这样理解:

字符

人看到的:

hello 你好

字节 Byte

计算机实际处理的一小块数据:

1 byte = 8 bit

二进制

计算机底层使用:

0 1

编码

规定:

一个字符应该如何转换成字节。

例如:

UTF-8 ASCII UTF-16

十六进制

只是为了方便人类阅读二进制数据的一种表示方式。

例如:

104

可以表示成:

0x68

所以:

十进制 104 ↓ 十六进制 68 ↓ 二进制 01101000

它们表示的是同一个数。


二十九、一张图理解 Buffer

最终可以把 Buffer 理解成:

JavaScript │ │ 字符串 ↓ ┌───────────┐ │ 编码 │ │ UTF-8 │ └─────┬─────┘ ↓ 二进制字节数据(0/1组合) ↓ ┌──────────────────┐ │ Buffer │ │ │ │e4 bd a0 e5 a5 bd │ └──────────────────┘ │ │ 解码 ↓ '你好'

所以 Buffer 的核心就是:

在 Node.js 中,Buffer 是处理二进制字节数据的重要工具。


三十、新手现阶段记住这几个就够了

如果你刚开始学习 Node.js,不需要一次把 Buffer 所有 API 都记住。

先掌握:

// 创建 BufferBuffer.alloc()Buffer.allocUnsafe()Buffer.from()// Buffer 长度buf.length// 读取buf[0]// 修改buf[0]=100// Buffer → 字符串buf.toString()// Buffer 拼接Buffer.concat()

然后理解下面这几个概念:

1 byte = 8 bit 1 byte = 0 ~ 255 Buffer 是二进制数据容器 Buffer.length 表示字节数 字符串和 Buffer 可以相互转换 Buffer.from() 可以创建 Buffer buf.toString() 可以把 Buffer 转回字符串 英文字符通常占 1 个字节 UTF-8 中文字符通常占 3 个字节

最后把这一条记住:

JavaScript 字符串 ↓ 编码 ↓ 字节 ↓ Buffer ↓ Node.js 处理 ↓ Buffer ↓ 解码 ↓ JavaScript 字符串

这就是 Buffer 最核心的工作原理。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/21 4:01:12

多元奇异谱分析(MSSA):多变量时间序列联合分解实战指南

1. 什么是多元奇异谱分析&#xff08;MSSA&#xff09;&#xff1f;它到底能解决什么实际问题&#xff1f;“多元奇异谱分析”——这个词刚听上去确实有点学术味儿重&#xff0c;但别急着划走。我第一次在某高校实验室的气象数据处理项目里见到它时&#xff0c;也以为是又一个披…

作者头像 李华
网站建设 2026/10/21 4:01:13

一文读懂荧光标记脂质:DOPE-FITC与FITC-PEG-DOPE的合成与应用

做纳米药物递送的人&#xff0c;应该都见过DOPE-FITC和FITC-PEG-DOPE这种缩写。我第一次看到的时候也愣了半天&#xff0c;DOPE是磷脂&#xff0c;FITC是荧光染料&#xff0c;连在一起到底是干什么用的&#xff1f;后来真正开始给脂质纳米颗粒做细胞摄取和体内分布追踪&#xf…

作者头像 李华
网站建设 2026/10/21 4:01:11

体系 2 · 排序与结构体 讲义

结构体 排序是普及组的必考核心地基&#xff1a;多关键字排序、数据分组排序、复杂对象排序、贪心前的预处理&#xff0c;几乎都建立在它之上。 学习目标 掌握结构体定义、赋值、结构体数组掌握 sort 默认排序与自定义 cmp掌握单 / 多关键字优先级排序&#xff08;真题高频&…

作者头像 李华