Node.js buf.toString vs String.fromCharCode

zam*_*uts 4 character-encoding node.js

我试图显示字符í0xed(237).

String.fromCharCode 产生正确的结果:

String.fromCharCode(0xed); // 'í'
Run Code Online (Sandbox Code Playgroud)

但是,使用时Buffer:

var buf = new Buffer(1);
buf.writeUInt8(0xed,0); // <Buffer ed>
buf.toString('utf8'); // '?', same as buf.toString()
buf.toString('binary'); // 'í'
Run Code Online (Sandbox Code Playgroud)

使用'binary'with Buffer.toString不赞成的,所以我想避免这种情况.

其次,我还可以预期传入的数据是多字节的(即UTF-8),例如:

String.fromCharCode(0x0512); // ? - correct
var buf = new Buffer(2);
buf.writeUInt16LE(0x0512,0); // <Buffer 12 05>, [0x0512 & 0xff, 0x0512 >> 8]
buf.toString('utf8'); // ? - correct
buf.toString('binary'); // Ô
Run Code Online (Sandbox Code Playgroud)

请注意,这两个示例都不一致.

那么,我错过了什么?我假设我不应该做什么?是String.fromCharCode神奇吗?

Jon*_*ski 7

似乎你可能假设Strings和Buffers使用相同的位长和编码.

JavaScript String16位UTF-16序列,而Node Buffer是8位序列.

UTF-8也是一种可变字节长度编码,代码点消耗在1到6个字节之间.í例如,UTF-8编码占用2个字节:

> new Buffer('í', 'utf8')
<Buffer c3 ad>
Run Code Online (Sandbox Code Playgroud)

并且,它本身0xed不是UTF-8编码中的有效字节,因此?表示"未知字符".但是,它是一个有效的UTF-16代码String.fromCharCode().

此外,您建议的第二个示例的输出似乎不正确.

var buf = new Buffer(2);
buf.writeUInt16LE(0x0512, 0);
console.log(buf.toString('utf8')); // "\u0012\u0005"
Run Code Online (Sandbox Code Playgroud)

你可以绕道而行,String.fromCharCode()看看UTF-8编码.

var buf = new Buffer(String.fromCharCode(0x0512), 'utf8');
console.log(buf); // <Buffer d4 92>
Run Code Online (Sandbox Code Playgroud)