Node.js中Buffer缓冲区

2019-08-26115次阅读node

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 技

可以看到已经正常输出了

 
上一篇: npm常用指令  下一篇: Swig模版输出不转义的HTML代码  

Node.js中Buffer缓冲区相关文章