在应用程序中,你有两个基本模型:
- 在整个应用程序中使用UTF-16。
- 在整个应用程序中使用UTF-8字符串,并在Win32 API / MFC / ...调用时进行UTF-16的转换。
如果你将大量使用不支持UTF-16的库,则第一个模型可能会有问题。但实际上,我从未发现这是一个问题。有些人会告诉你,仅仅因为你使用UTF-16,你就是愚蠢的,你的产品注定失败,但我从未发现这是一个问题。
如果你屈服于同行的压力,或者依赖于现有的以UTF-8为中心的代码,则在使用自定义包装类将字符串转换为/从CString(以及一些处理
[out] CString *
/
CString &
的帮助类)时,使用UTF-8内部可以得到简化。对于非MFC非CString代码,
std::vector<TCHAR>
是一个很好的表示形式。当然,该包装器不应隐式地转换为/从char *或wchar_t *。
在读写文件时,只要它们是“你的”应用程序文件,你可以随心所欲地处理。事实上,使用不透明(二进制)格式可能会完全隔离用户问题。只需保持一致即可。
问题出现在你开始处理来自其他应用程序的文件,或者用户可以使用其他应用程序编辑你的应用程序文本文件时。这就是它开始变得黯淡的地方。由于多年来对UTF-8的支持非常有限,因此许多工具无法很好地处理它。其他程序确实能够正确识别和解释UTF-8,但无法跳过任何存在的BOM标记。
尽管如此,UTF-8是“未来的安全投注”。即使它需要更多的开发,我强烈建议在共享文件中使用它。
我们的解决方案经过一番讨论之后,如下所示:
读取文本文件时,默认算法为:
- 探测BOM。如果存在,则依赖于BOM(但当然要跳过它)
- 探测有效的UTF-16(我们甚至支持LE / BE,尽管BE不太可能出现)。
- 探测ASCII(所有字节<= 127)。如果是,则将其解释为ASCII。
- 探测UTF-8。如果正文是有效的UTF-8,则读取为UTF-8。
- 否则回退到当前代码页。
UTF-8是专门设计的,以便任何其他编码实际上都是有效的UTF-8的可能性非常非常低。这使得最后两个步骤的顺序相当安全。
在写入文本文件时,我们使用没有BOM的UTF-8。从我们使用的外部工具的简短、信息性调查来看,这是最安全的选择。
基于此,我们还包括了一种工具,使我们的开发人员和用户可以检测和转换非UTF-8文本文件为UTF-8。