Buffer是存放二进制数据容器,类似Python的Byte类型。
// utf-8 编码
jmjc_utf8 = new Buffer('简明教程', 'utf-8')
console.log(jmjc_utf8) // <Buffer e7 ae 80 e6 98 8e e6 95 99 e7 a8 8b>
// utf-8 解码
jmjc = jmjc_utf8.toString()
console.log(jmjc) // 简明教程
缓冲区
Buffer 除了转码的作用外,它更多时候还用作缓冲区,用于数据的缓存。
var buf = new Buffer(10) // 定义一个10字节的 Buffer
buf.write('...') // 缓存数据
console.log(buf) // <Buffer 2e 2e 2e 00 00 00 00 00 00 00>
console.log(buf.toString()) // ...
Base64
Buffer 的 toString 方法,还提供了 Base64 数据的转换。
var b = new Buffer('JavaScript')
var s = b.toString('base64')
// SmF2YVNjcmlwdA==
var b = new Buffer('SmF2YVNjcmlwdA==', 'base64')
var s = b.toString()
// JavaScript
在 6.0.0之前的Node.js版本中, Buffer实例是使用 Buffer构造函数创建的,该函数根据提供的参数以不同方式分配返回的 Buffer new Buffer()。
现在可以通过 Buffer.from()、Buffer.alloc() 与 Buffer.allocUnsafe() 三种方式来创建
Buffer.from()
const b1 = Buffer.from('10');
const b2 = Buffer.from('10', 'utf8');
const b3 = Buffer.from([10]);
const b4 = Buffer.from(b3);
console.log(b1, b2, b3, b4); // <Buffer 31 30> <Buffer 31 30> <Buffer 0a> <Buffer 0a>
Buffer.alloc
返回一个已初始化的Buffer,可以保证新创建的Buffer永远不会包含旧数据。
const bAlloc1 = Buffer.alloc(10); // 创建一个大小为 10 个字节的缓冲区
console.log(bAlloc1); // <Buffer 00 00 00 00 00 00 00 00 00 00>
Buffer.allocUnsafe
创建一个大小为size字节的新的未初始化的Buffer,由于Buffer是未初始化的,因此分配的内存片段可能包含敏感的旧数据。在Buffer内容可读情况下,则可能会泄露它的旧数据,这个是不安全的,使用时要谨慎。
const bAllocUnsafe1 = Buffer.allocUnsafe(10);
console.log(bAllocUnsafe1); // <Buffer 49 ae c9 cd 49 1d 00 00 11 4f>
Buffer字符编码
通过使用字符编码,可实现 Buffer 实例与 JavaScript 字符串之间的相互转换,目前所支持的字符编码如下所示:
- 'ascii' - 仅适用于 7 位 ASCII 数据。此编码速度很快,如果设置则会剥离高位。
- 'utf8' - 多字节编码的 Unicode 字符。许多网页和其他文档格式都使用 UTF-8。
- 'utf16le' - 2 或 4 个字节,小端序编码的 Unicode 字符。支持代理对(U+10000 至 U+10FFFF)。
- 'ucs2' - 'utf16le' 的别名。
- 'base64' - Base64 编码。当从字符串创建 Buffer 时,此编码也会正确地接受 RFC 4648 第 5 节中指定的 “URL 和文件名安全字母”。
- 'latin1' - 一种将 Buffer 编码成单字节编码字符串的方法(由 RFC 1345 中的 IANA 定义,第 63 页,作为 Latin-1 的补充块和 C0/C1 控制码)。
- 'binary' - 'latin1' 的别名。
- 'hex' - 将每个字节编码成两个十六进制的字符。
const buf = Buffer.from('hello world', 'ascii');
console.log(buf.toString('hex')); // 68656c6c6f20776f726c64
字符串转Buffer
这个相信不会陌生了,通过上面讲解的Buffer.form()实现,如果不传递 encoding默认按照UTF-8 格式转换存储
const buf = Buffer.from('Node.js 技术栈', 'UTF-8');
console.log(buf); // <Buffer 4e 6f 64 65 2e 6a 73 20 e6 8a 80 e6 9c af e6 a0 88>
console.log(buf.length); // 17
Buffer转换为字符串
Buffer转换为字符串也很简单,使用toString([encoding], [start], [end]) 方法,默认编码仍为 UTF-8,如果不传 start、end 可实现全部转换,传了 start、end 可实现部分转换(这里要小心了)
const buf = Buffer.from('Node.js 技术栈', 'UTF-8');
console.log(buf); // <Buffer 4e 6f 64 65 2e 6a 73 20 e6 8a 80 e6 9c af e6 a0 88>
console.log(buf.length); // 17
console.log(buf.toString('UTF-8', 0, 9)); // Node.js �
运行查看,可以看到以上输出结果为 Node.js � 出现了乱码,为什么?
转换过程中为什么出现乱码?
首先以上示例中使用的默认编码方式 UTF-8,问题就出在这里一个中文在UTF-8 下占用3个字节,技这个字在 buf 中对应的字节为 8a 80 e6
而我们的设定的范围为 0~9 因此只输出了8a,这个时候就会造成字符被截断出现乱码。
下面我们改下示例的截取范围:
const buf = Buffer.from('Node.js 技术栈', 'UTF-8');
console.log(buf); // <Buffer 4e 6f 64 65 2e 6a 73 20 e6 8a 80 e6 9c af e6 a0 88>
console.log(buf.length); // 17
console.log(buf.toString('UTF-8', 0, 11)); // Node.js 技
可以看到已经正常输出了