Buffer模块
内存空间的开辟是连续的,从左到右
- Buffer是nodejs可以用来处理二进制流数据
Buffer使用连续的内存块来存储数据,可以更高效地利用内存。这在处理大文件或大量二进制数据时尤为重要,因为可以避免不必要的内存分配和复制操作- 用来操作网络协议、数据库、图片和文件I/O等一些需要二进制的数据的场景
核心api
- Buffer.form
- 创建包含指定字符串,数组或缓冲区的新缓冲区
- Buffer.alloc
- 创建一个并且初始化一个
Buffer - 可以指定创建的内存空间buffer
- 可以保证创建的Buffer永远不会包含旧数据
- 创建一个并且初始化一个
- Buffer.allocUnsafe
- 创建一个指定大小的新
Buffer,但不初始化其内容 - 由于Buffer是未初始化的,因此分配的内存片段可能包含敏感的旧数据。在Buffer内容可读情况下,则可能会泄露它的旧数据,这个是不安全的,使用时要谨慎
- 创建一个指定大小的新
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字符串之间的相互转换,目前所支持的字符编码如下所示
| 编码名称 | 描述 |
|---|---|
ascii | 7 位 ASCII 数据。如果设置高位,则会被截断。 |
utf8 | 多字节编码的 Unicode 字符。 |
utf-8 | 与 utf8 相同,许多网页和其他文档格式都使用UTF-8 |
utf16le | 2 或 4 字节,小端序编码的 Unicode 字符。 |
ucs2 | utf16le 的别名。 |
ucs-2 | 与 ucs2 相同。 |
base64 | Base64 编码。 |
latin1 | 一种将 Buffer 直接转成一字节编码字符串的编码方式。 |
binary | latin1 的别名。 |
hex | 将每个字节编码为两个十六进制字符。 |
// 创建 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不会一次性加载到内存中,而是分块读取和写入
-
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.');
});
});