2013-08-22 41 views
3

我試圖從0xed(237)顯示字符íNode.js buf.toString vs String.fromCharCode

String.fromCharCode得到正確的結果:

String.fromCharCode(0xed); // 'í' 

然而,在使用時Buffer

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

使用 '二進制' 與Buffer.toString是要deprecated所以我想避免這種情況。

其次,我還可以期待進入的數據爲多字節(即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'); // Ô 

注意,這兩個例子中是不一致的。

所以我錯過了什麼?我假設我不應該這樣做?神奇的是String.fromCharCode

回答

6

似乎你可能會認爲String s和Buffer s使用相同的位長和編碼。

JavaScript String s是16-bit, UTF-16 sequences而Node的Buffer s是8位序列。

UTF-8也是一種可變字節長度編碼,代碼點消耗爲between 1 and 6 bytes。的í的UTF-8編碼,例如,佔用2個字節:

> new Buffer('í', 'utf8') 
<Buffer c3 ad> 

而且,在其自己的,0xed不在UTF-8編碼的有效字節,因此代表一個的?「未知字符」。但是,它是一個有效的UTF-16代碼,可用於String.fromCharCode()

此外,您建議的第二個示例的輸出看起來不正確。

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

您可以繞道String.fromCharCode()查看UTF-8編碼。

var buf = new Buffer(String.fromCharCode(0x0512), 'utf8'); 
console.log(buf); // <Buffer d4 92> 
+1

我不知道s4.3.16,所以謝謝你。原來我忽略了二進制數據文件中的編碼:它是ISO-8859-1。 * doh *使用Iconv我能夠成功轉碼:var v = new Iconv('ISO-8859-1','UTF-8'); v.convert(BUF)的ToString( 'UTF8');'。 – zamnuts