25-二进制解码-string_decoder

110 阅读2分钟

二进制解码-string_decoder

// string_decoder 模块用于将Buffer转成对应的字符串,使用者通过调用 StringDecoder.write(buffer),可以获得buffer对应的字符串,
// 他的特殊之处在于,当传入buffer不完整,(比如三个字节的字符,只传入了两个),内部会维护一个 internal buffer 将不完整的字节 cache 住,等到使用者再次调用 StringDecoder.write(buffer) 传入剩下的字节,来拼成完整的字符
// 这样可以有效的避免buffer不完整带来的错误,对于很多场景,比如网络请求的包体解析等

入门案例

decoder.write(buffer) decoder.end([buffer])

decoder.write(buffer)

// decoder.write(buffer) 调用传入了Buffer对象,<Buffer e4 bd a0>,相应的返回对应的字符串 你
const StringDecoder = require("string_decoder").StringDecoder;
const decoder = new StringDecoder("utf8");
const str = decoder.write(Buffer.from([0xe4, 0xbd, 0xa0]));
console.log(str); // 你

decoder.end([buffer])

// 当被调用的时候,内部剩余的buffer会被一次性返回,如果此时带上 buffer 参数,name相当于同时调用 decoder.write(buffer) 和 decoder.end()
const StringDecoder = require("string_decoder").StringDecoder;
const decoder = new StringDecoder("utf8");
let str = decoder.write(Buffer.from([0xe4, 0xbd, 0xa0, 0xe5, 0xa5]));
console.log(str); // 你
str = decoder.end(Buffer.from([0xbd]));
console.log(str); // 好

多次写入多个字节

// 下面例子,演示了分多次写入多个字节时,string_decoder模块是怎么处理

// 首先,传入了`<Buffer e4 bd a0 e5 a5>`,`好`还差1个字节,此时,`decoder.write(xx)`返回`你`。
// 然后,再次调用 decoder.write(Buffer.from([0xbd])) 将剩余一个字节传入,成功返回 好
const StringDecoder = require("string_decoder").StringDecoder;
const decoder = new StringDecoder("utf8");
let str = decoder.write(Buffer.from([0xe4, 0xbd, 0xa0, 0xe5, 0xa5]));
console.log(str); // 你
str = decoder.write(Buffer.from([0xbd]));
console.log(str); // 好

decoder.end()时, 字节数不完整的处理

// decoder.end(buffer) 时,仅传入了 好 一个字节,此时调用 decoder.end() 返回了 � ,对应的bufer为 <Buffer ef bf bd>
const StringDecoder = require("string_decoder").StringDecoder;
const decoder = new StringDecoder("utf8");
let str = decoder.end(Buffer.from([0xe5]));
console.log(str); // �
console.log(Buffer.from(str)); // <Buffer ef bf bd>

// 官方文档对于这种情况的解释是这样的,大约是约定俗成的,当utf-8码点无效时,替换成 ed bf bd
// >以字符串形式返回存储在内部缓冲区中的所有剩余输入。表示不完整UTF-8和UTF-16字符的字节将替换为适合字符编码的替换字符。

相关链接

// 你应该记住的一个UTF-8字符「EF BF BD」
// http://liudanking.com/golang/utf-8_replacement_character/