Buffer 是 Node.js 在内存中开辟的一块固定大小的物理内存区域,专门用来存放原始的二进制数据。
Stream 是 Node.js 处理大体积数据或逐块处理数据的机制。
接下来由于刚刚学习过TCP\UDP\Http网络编程基础,但网络传输就离不开数据流,数据流是 Node.js 中数据底层载体,缓冲区与流,本文主要记录我在学习 Node.js 数据流时的笔记整理
以上几种的区别就像是 计算机(数据流)>笔记本(tcp)>平板电脑(http)>iphone手机(udp),这是我的理解
计算机是根本、笔记本是计算机的应用、平板电脑是笔记本的二次封装、 iphone手机直接对接计算机,并封闭自身系统确保外部内容无法影响自身
Node.js 中有四种基本流类型:
如在我计划中会学习如何操作sqlite,就需要调用sqlite模块进行创建文件,读取文件就属于创建流的一部分,或是在往期我的日志系统fs文件读写也是流在实际使用的场景
流给我的感受就是,在流传输时他才叫做流,当流存入文件后,这时候的流他就叫文件内容了,明白了什么是流,就明白了TCP、UDP、HTTP他们在两个端交互的本质,就是互相交流达到各自想要的效果,嘿嘿嘿好贴切
// 创建个log.txt文件用来存储流const writeStream = fs.createWriteStream('./log.txt');// 方式1: 将“hello world”以流的方式写入log文件fs.writeFileSync('log.txt', 'hello world', 'utf8');// 方式2:向writeStream流中写入数据writeStream.write('hello world\n');// 方式3: 向log文件中追加数据fs.appendFile('log.txt', 'hello world\n', (err) => { /* ... */ });// 标记流写入结束writeStream.end();在hello word准备写入log.txt文件时,尚未写入完成前,这个期间的hello word会转成计算机的二进制语言,这个二进制数据就是流,hello word不过是计算机为了让我们能看懂的表现形式
01101000 01100101 01101100 01101100 01101111 00100000 01110111 01101111 01110010 01101100 01100100 (h) (e) (l) (l) (o) (空格) (w) (o) (r) (l) (d)好了以上就是我对流的理解,也完成了我对流的学习目标,对于如何操作流nodejs还提供了很多函数,我就不一一说明了,有兴趣的兄弟可以在文章末尾查看网址,自行浏览了
Buffer在内存中开辟的固定大小的区域,专门用来存放二进制数据。Buffer在流传输的过程中,将流打包为一个个的chunk,如果你对webpack或vite熟悉,那么你对chunk形式就比较熟悉,在打包编译时,将各个依赖进行打包,这个chunk包就是chunk.js,buffer起到的作用就是这样,将流存储到buffer中,一个buffer满了存下一个buffer
如果你做过大文件切片上传,那么就更好理解了,buffer就是你大文件切完的片,片内存储的就是文件的一部分流
Buffer 类是一个全局变量,就像JS内置的String、Object等对象一样,他在Node.js中是内置的无需进行引用
Buffer.alloc(size) — 创建清零的 Buffer(安全、稍慢)这个方法会在内存中申请一块指定大小(以字节 Byte 为单位)的内存区域,并且会自动把里面的数据全部清零(用 00 填充)。
// 创建一个可以容纳 5 个字节的 Bufferconst buf = Buffer.alloc(5);console.log(buf); // 输出: <Buffer 00 00 00 00 00> (全部被清零)Buffer.allocUnsafe(size) — 创建未初始化的 Buffer(危险、极快)这个方法同样是申请指定大小的内存,但它不会清零。这意味着它分配出来的内存里,可能还残留着之前其他程序用过的数据。
// 创建一个 5 字节未初始化的 Bufferconst bufUnsafe = Buffer.allocUnsafe(5);console.log(bufUnsafe); // 输出可能是: <Buffer 80 a4 3f 02 00> (里面是内存残留的垃圾数据)Buffer.from() — 根据已有数据创建 Buffer(最常用)这个方法非常智能,它可以把字符串、数组、或者是另一个 Buffer 直接转换成二进制的 Buffer。
默认会将字符串以 UTF-8 编码转换为二进制。
// 从字符串创建const bufStr = Buffer.from('hello');console.log(bufStr); // 输出: <Buffer 68 65 6c 6c 6f> (这是 hello 对应的十六进制 ASCII 码)console.log(bufStr.toString()); // 输出: 'hello' (转回字符串)传入的数组元素必须是 0 到 255 之间的数字(因为一个字节最大就是 255)。
// 传入十进制数组const bufArr = Buffer.from([104, 101, 108, 108, 111]);console.log(bufArr.toString()); // 输出: 'hello' (104对应h, 101对应e...)在处理网络协议或加密(如 MD5/SHA256)时,经常需要处理十六进制字符串。你可以传入第二个参数来指定编码。
// 告诉 Node.js 这一串是十六进制数据const bufHex = Buffer.from('68656c6c6f', 'hex');console.log(bufHex.toString()); // 输出: 'hello'Buffer.from()。Buffer.alloc()(图省事安全)或 Buffer.allocUnsafe()(图极致性能)。stream 流文档https://node.org.cn/docs/latest/api/stream.html#stream
buffer 缓冲区文档https://node.org.cn/docs/latest/api/stream.html#buffering
👉往期推荐: