|
转的
【转帖】“微软对移动和联通的不公”的原因
有这样一个帖子:微软对移动和联通的不公
如果你的电脑操作系统是WIN2000或WINXP/2003的话,那么:
1,在桌面上点右键,选择新建 — 文本文档;
2,打开"新建 文本文档",录入"移动"两字后存盘退出;
3,重新打开"新建 文本文档",看到什么了?
4,是不是刚刚录入的"移动"两字?
咱们换过来
1,在桌面上点右键,选择新建 — 文本文档;
2,打开"新建 文本文档",录入"联通"两字后存盘退出;
3,重新打开"新建 文本文档",看到什么了?
4,是不是刚刚录入的"联通"两字不见了,取而代之是个烧焦的手机电池(一个符号)!!!
*****************
我也不禁试了一下,果然如此。不过总觉得微软还不至于如此厚此薄彼,总应该是有什么原因的吧?
因为我习惯使用的文本编辑工具不是 Notepad,而是 EmEditor,经过仔细察看,原来重新打开“联通”两个字的文本文件时,使用的是 Utf-8 格式。这一下就豁然开朗 —— 只是因为“联通”这两个字的 GB2312 编码会被误判为 Utf-8 编码,所以才出现这种情况,人为的选择“系统默认”编码打开这个文件,这个文件就可以正常显示了。
这个问题是因为文本文件编码格式太多种,所以 Windows 有提供一个 API 来分析一个文件是使用哪种编码格式的,不过,这种分析本身不能提供真正准确的结果 —— 特别是对于短小的文件。例如一个文件只包含 ASCII 的话,则既可以认为它是 ASCII 文件,也可以认为是 GB2312 格式(因为 GB2312 兼容 ASCII),也可以认为 Utf-8(因为 ASCII 的 Utf-8 和原码相同),所以这个分析函数只能返回其中的一种可能的格式,而这个格式就可能和用户的愿望不同。所以,从根本上说,这不止不是厚此薄彼,甚至不能算是一个 Bug,而只是一个在证据不足的情况下的一个合理但不正确的臆测而已……
因为这种情况,所以其实保存 UniCode 和 Utf-8 格式的文件的时候,可以选择有“签名”的格式,这种格式的文本文件,文件头部有一个标识符,说明这个文件是什么格式,这样,就不再需要用那个分析函数去猜测这个文件的格式,也就总是能够正确地读取和保存了。
另外,使用 UniCode 和 Utf-8 格式的话,可以在同一个文件中保存多国语言,不止日文,像韩文、德文、法文、阿拉伯文等等,都可以共存于一个文件中,而不会有任何冲突,虽然可能会比 GB2312 格式的文件个头稍微大一点,不过还是发展的趋势,算是一个比较不错的选择,唯一可能有问题的地方是,如果要和他人交换文件,就需要对方也能读取这种格式才行。
我们已经知道这只不过是一个微软的程序的BUG,但是究竟为什么会出现这样的情况呢?在新闻评论中,已经有读者为我们作出了解释:
评论[26]网友:Soft于2003年12月10日13:24
记事本的编码问题,当文档中所有字符都在 C0≤AA≤DF80≤BB≤BF这个范围的时候,notepad都无法确认文档的格式,没有自动按照UTF-8格式来"Display"。 "联通"就是C1AA CDA8,刚好在上面的范围内,所以不能正常显示。
但是由于不够详细,笔者就这一问题又特地咨询了放飞技术网的高工(姓高,当然技术水平也特高),高工非常热心的给我们带来了更加详细的解释:
在计算机中字符通常并不是保存为图像,每个字符都是使用一个编码来表示的,而每个字符究竟使用哪个编码代表,要取决于使用哪个字符集(charset)。
在最初的时候,Internet上只有一种字符集——ANSI的ASCII字符集,它使用7bits来表示一个字符,总共表示128个字符,其中包括乐英文字母、数字、标点符号等常用字符。之后,又进行扩展,使用8bits表示一个字符,可以表示256个字符,主要在原来的7bits字符集的基础上加入了一些特殊符号例如制表符。
后来,由于各国语言的加入,ASCII已经不能满足信息交流的需要,因此,为了能够表示其它国家的文字,各国在ASCII的基础上制定了自己的字符集,这些从ANSI标准派生的字符集被习惯的统称为ANSI字符集,它们正式的名称应该是MBCS(Multi-ByteChactacterSystem,即多字节字符系统)。这些派生字符集的特点是以ASCII 127bits为基础,兼容ASCII127,他们使用大于值128的编码作为一个LeadingByte,紧跟在LeadingByte后的第二(甚至第三)个字符与LeadingByte一起作为实际的编码。这样的字符集有很多,我们常见的GB-2312就是其中之一。
例如在GB-2312字符集中,“联通”的编码为0xC1,0xAA,0xCD,0xA8,其中0xC1和0xCD就是LeadingByte。前127个编码为标准ASCII保留,例如“0”的编码是0x30。软件在读取时,如果看到0x30,知道它小于128就是标准ASCII,表示“0”,看到0xC1大于128就知道它后面有一个另外的编码,因此0xC1,0xAA一同构成一个整个的编码,在GB-2312字符集中表示“联”。
由于每种语言都制定了自己的字符集,导致最后存在的各种字符集实在太多,在国际交流中要经常转换字符集非常不便。因此,提出了Unicode字符集,它固定使用16bits(两个字节、一个字)来表示一个字符,共可以表示65536个字符。将世界上几乎所有语言的常用字符收录其中,方便的信息交流。标准的Unicode成为UTF-16。后来为了双字节的Unicode能够在现存的处理单字节的系统上正确传输,出现了UTF-8,适用类似MBCS的方式对UTF-16进行编码。注意UTF-8是编码,它属于Unicode字符集,
最后,当一个软件打开一个文本时,它要做的第一件事是决定这个文本究竟是使用哪种charset编码的。软件有三种入境途径来决定文本的charset:
最标准的途径是检测文本最开头的几个字节,如下表:
开头字节 Charset/encodingEF BB BF UTF-8FE FF UTF-16/UCS-2,littleendianFF FE UTF-16/UCS-2, big endianFF FE 00 00UTF-32/UCS-4,little endian.00 00 FE FF UTF-32/UCS-4,big-endian.
但是很多文本,尤其是早期软件生成的文本,没有这些位于开头的字符集标记,这时,软件可以采取一种比较安全的方式来决定charset,那就是弹出一个对话框来请示用户,例如将那个“联通”文件拖到MSWord中,Word就会弹出一个对话框。
如果软件不想麻烦用户,或者它不方便向用户请示,那它只能采取自己“猜”的方法,软件可以根据整个文本的特征来猜测它可能属于哪个charset,这就很可能不准了。使用记事本打开那个“联通”文件就属于这种情况。
我们可以证明这一点:在记事本中键入“联通”后,选择“SaveAs”,会看到最后一个下拉框中显示有“ANSI”,这时保存。当再当打开“联通”文件出现乱码后,再点击“File”->“SaveAs”,会看到最后一个下拉框中显示有“UTF-8”,这说明记事本认为当前打开的这个文本是一个UTF-8编码的文本。而我们刚才保存时是用ANSI字符集保存的。这说明,记事本猜测了“联通”文件的字符集,认为它更像一个UTF-8编码文本。这是因为“联通”两个字的GB-2312编码看起来更像UTF-8编码导致的,这是一个巧合,不是所有文字都这样。可以使用记事本的打开功能,在打开“联通”文件时在最后一个下拉框中选择ANSI,就能正常显示了。反过来,如果之前保存时保存为UTF-8编码,则直接打开也不会出现问题。
如果将“联通”文件放入MSWord中,Word也会认为它是一个UTF-8编码的文件,但它不能确定,因此会弹出一个对话框询问用户,这时选择“简体中文(GB2312)”,就能正常打开了。记事本在这一点上做得比较简化罢了,这与这个程序的定位是一致的。
我们再次感谢高工给我们带来的解释,让我们对这一现象有了比较清楚的认识。
|
|