2010-12-05 64 views

回答

5

张贴在What every developer should know about character encoding

如果你编写触及文本文件的代码,你可能需要这个。

让我们开始了与两个关键项目

1.Unicode不能解决这个问题对我们(还)。

2.每个文本文件都被编码。不存在未编码文件或“一般”编码。 让我们为此添加一条鳕鱼 - 大多数美国人可以在不需要考虑这一点的情况下获得 - 大部分时间。因为绝大多数编码方案中前127个字节的字符映射到同一组字符(更准确地称为字形)。而且,因为我们只使用没有任何其他字符,口音等的A-Z,所以我们很好。但是,第二个在HTML或XML文件中使用这些假设的前提是127以外的字符 - 然后就会出现问题。

计算机工业从磁盘空间和内存开始,任何人建议每个字符使用2个字节而不是1个字符会被嘲笑。事实上,我们很幸运的是,字节在8位时效果最好,或者每个字符的字节数可能少于256位。当然有很多字符(或代码页)在早期开发。但是我们最后大部分人都使用了一组标准的代码页,其中前127个字节是全部相同的,而第二个是每个集唯一的。对于美国/西欧,中欧,俄罗斯等国家,有一些集合。

然后对于亚洲来说,由于256个字符是不够的,128-255的范围中有一些被称为DBCS(双字节字符集) 。对于第一个字节的每个值(在这些更高的范围内),第二个字节随后标识256个字符中的一个。这给了总共128 * 256个额外的字符。这是一种黑客攻击,但它将内存使用量降到最低。中文,日文和韩文都有自己的DBCS代码页。

而且一段时间以来运作良好。操作系统,应用程序等主要被设置为使用指定的代码页。但随后互联网出现了。美国的一家网站使用来自希腊的XML文件向在俄罗斯浏览的用户显示数据,其中每个用户都在基于其国家/地区输入数据 - 这打破了范例。

快进到今天。 HTML和XML是我们可以解释的最好的两种文件格式,每个人都可以浏览它。每个HTML和XML文件可以选择在其标题元数据中设置字符编码。如果没有设置,那么大多数程序都假设它是UTF-8,但这不是一个标准,也没有普遍遵循。如果未指定编码并且读取文件的程序猜错 - 文件将被误读。

第1点 - 永远不要在编写文件时指定编码为可选。始终将其写入文件。总是。即使你愿意发誓该文件将永远不会有字符超出范围1-127。

现在让我们来看看UTF-8,因为作为标准和它的工作方式,它使人们变得很多的麻烦。 UTF-8流行的原因有两个。首先它匹配了前127个字符的标准代码页,因此大多数现有的HTML和XML都会匹配它。其次,它被设计成尽可能少地使用字节,这些字节在设计时很重要,许多人仍在使用拨号调制解调器。

UTF-8从亚洲代码页的DBCS设计中借用。前128个字节都是字符的单字节表示。然后,对于下一个最常见的设置,它使用第二个128字节中的一个块作为双字节序列,从而为我们提供更多字符。但是,等等,还有更多。对于不太常见的第一个字节会导致第二个字节的数量级。那些每个都会导致第三个字节,这三个字节定义字符。这可以达到6个字节的序列。使用MBCS(多字节字符集),您可以编写每个unicode字符的equivilent。假设你正在写的东西不是很少使用的汉字列表,用较少的字节做。

但是,这里是每个人都要旅行的东西 - 他们有一个HTML或XML文件,它工作正常,并且他们在文本编辑器中打开它。然后,他们在文本编辑器中添加一个字符,使用其区域的代码页,插入像ß这样的字符并保存该文件。当然,它必须是正确的 - 他们的文本编辑器显示正确。但将它提供给任何根据编码读取的程序,并且现在是第一个2字节序列的字符。您要么获得不同的字符,要么第二个字节不是第一个字节的合法值 - 这是一个错误。

第2点 - 在程序中始终创建HTML和XML,使用编码将其正确写出。如果您必须使用文本编辑器创建,请在浏览器中查看最终文件。

现在,你正在编写的代码将读取或写入一个文件呢?我们不是在以自己的格式写出二进制/数据文件,而是将文件视为文本文件。 Java,.NET等都有字符编码器。这些编码器的目的是在一系列字节(文件)和它们所代表的字符之间进行转换。让我们看看实际上是一个非常困难的例子 - 你的源代码,不管它是C#,Java等等。这些仍然是“普通的旧文本文件”,没有编码提示。那么,程序如何处理它们呢?许多人认为他们使用本地代码页。许多人认为所有角色的范围都在0-127之间,并且会扼杀其他任何东西。

这是关于这些文本文件的关键点 - 每个程序仍在使用编码。它可能不会在代码中进行设置,但根据定义,正在使用编码。

第3点 - 在读取和写入文本文件时始终设置编码。不仅仅适用于HTML & XML,即使对于源代码等文件也是如此。如果您将其设置为使用默认的代码页,但是设置了编码,那很好。

第4点 - 尽可能使用最完整的编码器。您可以将自己的XML编写为以UTF-8编码的文本文件。但是,如果您使用XML编码器编写它,那么它将在元数据中包含编码,并且您不会错误。 (它也添加了endian前导码到文件中。)

好吧,您正在阅读&正确写入文件,但是在代码中如何。那有什么?这是很容易的地方 - unicode。那就是那些在.NET运行时中创建的编码器所设计的目的。你读入并得到unicode。你写unicode并得到一个编码文件。这就是char类型为16位的原因,并且是用于字符的唯一核心类型。这可能是对的,因为今天的语言在这个问题上没有给你太多的选择。

第5点 - (对于那些已经出现一段时间的语言的开发者) - 始终在内部使用unicode。在C++中,这被称为宽字符(或类似的东西)。不要聪明地保存几个字节,内存很便宜,而且你有更重要的事情要做。

结束工作

我认为有两个关键项目要记住这里。首先,确保你正在使用编码来记录文本文件。其次,这实际上非常简单直接。人们很少搞砸如何使用编码,这是他们忽视了他们陷入困境的问题。

+0

第5点取决于您的平台。 `wchar_t`和UTF-16是Windows如何执行Unicode,但类Unix系统倾向于使用UTF-8。 – dan04 2010-12-14 05:06:59

相关问题