跳到主要内容

Buffer模块

内存空间的开辟是连续的,从左到右

  • Buffer是nodejs可以用来处理二进制流数据
  • Buffer 使用连续的内存块来存储数据,可以更高效地利用内存。这在处理大文件或大量二进制数据时尤为重要,因为可以避免不必要的内存分配和复制操作
  • 用来操作网络协议、数据库、图片和文件I/O等一些需要二进制的数据的场景

核心api

  • Buffer.form
    • 创建包含指定字符串,数组或缓冲区的新缓冲区
  • Buffer.alloc
    • 创建一个并且初始化一个Buffer
    • 可以指定创建的内存空间buffer
    • 可以保证创建的Buffer永远不会包含旧数据
  • Buffer.allocUnsafe
    • 创建一个指定大小的新 Buffer ,但不初始化其内容
    • 由于Buffer是未初始化的,因此分配的内存片段可能包含敏感的旧数据。在Buffer内容可读情况下,则可能会泄露它的旧数据,这个是不安全的,使用时要谨慎
js
const bf1 = Buffer.from("20") // 一个数字占一个字节
const bf2 = Buffer.from("a") // 一个单词占一个字节
const bf3 = Buffer.from("啊") // 一个中文占3个字节
console.log('bf1',bf1) // <Buffer 32 30>
console.log('bf2',bf2) // <Buffer 61>
console.log('bf3',bf3) // <Buffer e5 95 8a>
Buffer.alloc(10) // 创建一个大小为10个字节的缓冲区

Buffer特点​

  • 原始二进制数据:Buffer 类用于存储和操作固定大小的二进制数据块。
  • 内存管理:Buffer 直接分配内存,不会像 JavaScript 字符串那样进行垃圾回收,因此处理大数据时更高效。
  • 编码转换:Buffer 提供多种字符编码之间的转换方法,便于处理文本数据。

Buffer字符编码​

通过使用字符编码,可实现Buffer实例与JavaScript字符串之间的相互转换,目前所支持的字符编码如下所示

编码名称描述
ascii7 位 ASCII 数据。如果设置高位,则会被截断。
utf8多字节编码的 Unicode 字符。
utf-8与 utf8 相同,许多网页和其他文档格式都使用UTF-8
utf16le2 或 4 字节,小端序编码的 Unicode 字符。
ucs2utf16le 的别名。
ucs-2与 ucs2 相同。
base64Base64 编码。
latin1一种将 Buffer 直接转成一字节编码字符串的编码方式。
binarylatin1 的别名。
hex将每个字节编码为两个十六进制字符。
js
// 创建 Buffer 实例
const buffer = Buffer.from('Hello, World!', 'utf8');

// Buffer 转字符串
const str = buffer.toString('hex');
console.log(str); // 48656c6c6f2c20576f726c6421

// 字符串转 Buffer
const newBuffer = Buffer.from(str, 'hex');
console.log(newBuffer.toString('utf8')); // Hello, World!

Buffer案例​

  • 实现文件或者图片的拷贝

    • 通过fs模块读取图片文件,将文件内容存储在buffer的缓冲区

    • 在将buffer的数据写入目标文件中

    • 对于大文件来说,配合stream流来处理会更高效,通过stream不会一次性加载到内存中,而是分块读取和写入

js
const fs = require('fs');

// 通过 fs.readFile 读取图片文件
fs.readFile('img.png', (err, buffer) => {
if (err) {
return console.error('Error reading file:', err);
}

// 检查读取到的数据是否是 Buffer 实例
console.log(Buffer.isBuffer(buffer) && 'readFile 读取图片拿到的是 Buffer 数据');

// 把读取到的 Buffer 数据,通过 fs.writeFile 写入到一个新图片文件中
fs.writeFile('logo.png', buffer, (err) => {
if (err) {
return console.error('Error writing file:', err);
}
console.log('Image file copied successfully.');
});

// 再基于原始的 Buffer 创建一个新的 Buffer,通过 toString base64 解码为字符串打印出来
const base64Image = Buffer.from(buffer).toString('base64');
console.log(base64Image);

// base64Image 是 base64 后的字符串,传参给 from,同时指定编码生成一个新的 Buffer 实例
const decodedImage = Buffer.from(base64Image, 'base64');

// 比较两个 Buffer 实例的数据,并写入到一个新的图片中
console.log(Buffer.compare(buffer, decodedImage) === 0 && 'Buffers are identical');
fs.writeFile('img_decoded.jpg', decodedImage, (err) => {
if (err) {
return console.error('Error writing decoded image file:', err);
}
console.log('Decoded image file written successfully.');
});
});