Node.js 编程实战:理解 Buffer 与 Stream

在处理文件、网络请求、图片、音频等二进制数据时,JavaScript 在浏览器端往往依赖 Web API,而在后端环境中,Node.js 则提供了更底层、更高效的数据处理方式。Buffer 与 Stream 是 Node.js 中处理二进制数据的核心机制,它们构成了 Node.js 高性能 I/O 的基础。

本篇文章将从基础概念讲起,帮助你理解两者之间的关系、应用场景以及如何在实际项目中高效使用。


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

JavaScript 本身只提供字符串类型,没有原生的二进制数据结构。然而服务器程序需要处理的很多数据都不是文本,比如:

  • 图片、视频、音频
  • 文件读写
  • 网络传输的二进制内容
  • 压缩包、PDF 等

因此 Node.js 设计了 Buffer,它是一块专门用于存放二进制数据的内存区域,允许以更低层的方式与 I/O 系统交互。

示例:创建一个 Buffer 并写入数据。

js 复制代码
const buf = Buffer.from("Hello");
console.log(buf);  // <Buffer 48 65 6c 6c 6f>

打印出来的是十六进制表示的字节序列。


二、Buffer 的常用操作

1. 创建 Buffer

js 复制代码
Buffer.from("文本内容");      // 从字符串创建
Buffer.alloc(10);             // 分配固定大小的空 Buffer
Buffer.allocUnsafe(10);       // 更快但可能含有旧数据

2. 读取和修改内容

Buffer 就像字节数组:

js 复制代码
const buf = Buffer.from("ABC");
console.log(buf[0]);  // 65
buf[0] = 97;          // 修改为小写字母 a

3. Buffer 转字符串

js 复制代码
buf.toString("utf-8");

Buffer 本质上是二进制与文本之间的桥梁。


三、什么是 Stream?

在处理大文件时,一次性把全部内容读入内存不仅低效,还可能导致崩溃。为了解决这个问题,Node.js 提供了 Stream(流):一种能够持续、分块处理数据的机制。

Stream 的核心特点:

  • 不需一次性加载全部内容
  • 内存使用更低
  • 边读边处理,速度更快
  • 适合大型文件处理、网络传输场景

例如:读取一个 2GB 的视频文件,使用 Stream 能够流式处理,而不是占用 2GB 内存。


四、Node.js Stream 的四种类型

  1. Readable(可读流) 例如:文件读取、网络请求输入

  2. Writable(可写流) 如:文件写入、网络发送

  3. Duplex(双工流) 既可读又可写,如:TCP 连接

  4. Transform(转换流) 在读写过程中处理数据,如:压缩、加密

Stream 是 Node.js 快速处理 I/O 的核心工具。


五、使用 Stream 读取文件

这是最常见的应用场景之一。

js 复制代码
const fs = require("fs");

const rs = fs.createReadStream("input.txt", { encoding: "utf-8" });

rs.on("data", chunk => {
  console.log("读取到:", chunk);
});

rs.on("end", () => {
  console.log("读取完成");
});

文件会被分成多个小段按顺序读取,不会占用大量内存。


六、使用 Stream 写入文件

js 复制代码
const ws = fs.createWriteStream("output.txt");

ws.write("第一行\n");
ws.write("第二行\n");
ws.end("写入结束");

写入流同样是分块写入,避免大文件造成卡顿。


七、流的强大连接方式:pipe()

Stream 最典型的用法就是 管道(pipe)。你可以将一个可读流直接"输送"到可写流。

例如:复制文件

js 复制代码
fs.createReadStream("input.mp4")
  .pipe(fs.createWriteStream("copy.mp4"));

只需一行代码,就能实现高效的数据传输,且非常节省内存。


八、Buffer 与 Stream 的关系

两者并非互相对立,而是密不可分:

  • Stream 负责"流式分段处理"数据
  • Buffer 负责"存储每一段的二进制数据"

Stream 就像水流,Buffer 就像每一杯盛水的容器。 每次 Stream 分发的数据 chunk 本质上就是一个 Buffer。

例如:

js 复制代码
rs.on("data", chunk => {
  console.log(Buffer.isBuffer(chunk));  // true
});

理解这一点有助于你正确处理大数据流。


九、使用 Buffer 处理网络与二进制协议

在 TCP 通信、WebSocket、图像处理时,你会频繁遇到 Buffer。例如:

js 复制代码
socket.on("data", chunk => {
  // chunk 是 Buffer
});

很多底层协议都会用 Buffer 来解析消息结构,如获取长度、类型、内容等。


十、总结

Buffer 与 Stream 是 Node.js 面向 I/O 设计的两大关键机制:

  • Buffer 提供了操作二进制的能力,是文件、网络、加密等场景的基础。
  • Stream 提供了高效处理大规模数据的方式,使 Node.js 能轻松应对大型文件、实时传输等需求。

掌握它们不仅能写出更高性能的程序,还能帮助你理解 Node.js 在底层如何处理数据流动,为后续学习网络模块、文件系统与 HTTP 服务打下扎实基础。


相关推荐
一心赚狗粮的宇叔5 小时前
03.Node.js依赖包补充说明及React&Node.Js项目
前端·react.js·node.js
jbtianci5 小时前
Spring Boot管理用户数据
java·spring boot·后端
那我掉的头发算什么6 小时前
【Mybatis】Mybatis-plus使用介绍
服务器·数据库·后端·spring·mybatis
会算数的⑨6 小时前
Kafka知识点问题驱动式的回顾与复习——(一)
分布式·后端·中间件·kafka
Hx_Ma166 小时前
SSM搭建(三)Spring整合SpringMVC框架
java·后端·spring
William_cl6 小时前
ASP.NET路由长度约束精讲:[HttpGet (“{name:minlength (3)}“)] 字符长度限制吃透,附避坑指南 + 实战代码
后端·asp.net
-嘟囔着拯救世界-6 小时前
【2026 最新版】OpenAI 祭出王炸 GPT-5.3-Codex!Win11 + VSCode 部署保姆级教程
vscode·gpt·chatgpt·node.js·node·codex·gpt5
我命由我123456 小时前
Java 泛型 - Java 泛型通配符(上界通配符、下界通配符、无界通配符、PECS 原则)
java·开发语言·后端·java-ee·intellij-idea·idea·intellij idea
szhf786 小时前
SpringBoot Test详解
spring boot·后端·log4j