使用ascii编码读取文件

时间:2012-12-14 13:30:02

标签: node.js

文件:

脚本:

require("fs").readFile ("file", "ascii", function (e, d){
    console.log(d==="聵") //true
})

这怎么可能? 不是ascii字符,用3个字节编码,0xE881B5。我期望得到è\u0081µ因为ascii字符用单个字节编码。如果我使用“二进制”编码读取它打印为true,我期望用ascii编码...

require("fs").readFile ("file", "binary", function (e, d){
    console.log(d === "è\u0081µ") //true
})

这个结果是故意的吗?如果ascii编码返回与utf8编码相同的结果,那么为什么“ascii”是一个可能的参数?

编辑:

这是内容(使用HxD程序打开):

Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000  E8 81 B5                                         è.µ

require("fs").readFile ("file", function (e, d){
    console.log (d.toString ("ascii") === "聵") //true
    console.log (d.toString ("utf8") === "聵") //true
    console.log (d.toString ("binary") === "è\u0081µ") //true
    console.log (d) //<Buffer e8 81 b5>
})

问题已提交给开发者:https://github.com/joyent/node/issues/4413

3 个答案:

答案 0 :(得分:3)

快速回答是Node在从Buffer转换为字符串时没有任何魔力,无论是ascii还是utf8。你的utf8字符串完全无效ascii,所以我觉得理想情况下它会引发错误,但很明显它不会。我不希望è\u0081µ,因为它无效ascii

您可以看到in the Node source,从缓冲区转换为字符串的代码是...slice函数。 asciiutf8函数相同,导致您看到的行为。这些构造函数没有做任何花哨的事情,它们只需要一个字节序列并将其转换为JS字符串,假设它在该编码中有效。

两种编码之间的差异来自该文件中的AsciiWrite和Utf8Write函数,它们对待事物的方式不同。

例如:

new Buffer("聵", 'ascii') // <Buffer 75>
new Buffer("聵", 'utf8')  // <Buffer e8 81 b5>

正如您从测试中看到的那样,binary更符合您的要求。 binary遍历缓冲区中的每个字节,并返回一个字符串,其中每个代码点都具有该字节值。

(new Buffer([0xe8, 0x81, 0xb5])).toString('binary').charCodeAt(0); // 0xe8

答案 1 :(得分:0)

这是一个错误:

https://github.com/joyent/node/pull/4379

paddddiinnnnngggg

答案 2 :(得分:-1)

我不知道究竟是什么语言,我猜日语(如果我错了,请纠正我)。但我相信你提供的角色恰好属于ascii标准,Japanese character encodings

纯属巧合。
  

然而,Shift JIS有一个不幸的特性,它常常会破坏   任何解析器(读取编码文本的软件)都不是   专门设计来处理它。例如,文本搜索方法   如果它不是为Shift JIS设计的,可能会出现错误命中。 EUC,关于   另一方面,已经编写的解析器处理得更好   对于7位ASCII(因此在UNIX上使用EUC编码,其中很多   历史上,文件处理代码只是为英文编写的   编码)。但EUC并没有向后兼容JIS X 0201,即   第一个主要的日文编码进一步的复杂化是因为   原始Internet电子邮件标准仅支持7位传输   协议。因此,JIS编码被开发用于发送和接收   电子邮件。

     

在JIS等字符集标准中,并非所有必需字符   包含,所以有时使用gaiji(外字“外部字符”)   补充字符集。 Gaiji可能以。的形式出现   外部字体包,其中普通字符已被替换   新字符或新字符已添加到未使用的字符中   角色位置。但是,gaiji在互联网上并不实用   环境,因为必须使用文本传输字体集才能使用   gaiji。结果,这些字符写成类似或   更简单的字符,或者文本可能需要使用   支持所需的较大字符集(如Unicode)   字符。

我会尝试使用更多“异国情调”的角色,因为你的测试会失败。