设为首页 收藏本站
查看: 829|回复: 0

[经验分享] Windows文本文件编码

[复制链接]
累计签到:4 天
连续签到:1 天
发表于 2017-6-28 14:33:18 | 显示全部楼层 |阅读模式
  目录
  1 ANSI编码    2
  2 UTF16BE编码    2
  3 UTF16LE编码    2
  4 UTF-8编码    2
  5 BOM    3
  6 乱码    3
  7 总结    5
  如下图所示,在记事本里输入"编码",然后另存为的时候,有四种编码:
DSC0000.png

  图1
  按下表所示,四种编码存为四个文件:

  编码
  文件名
  ANSI
  A.txt
  Unicode
  U.txt
  Unicode big endian
  UB.txt
  UTF-8
  U8.txt
  使用VC++6.0或Visual Studio以二进制方式打开这四个文件。二进制编码一目了然,如下图所示:
DSC0001.png

  图2
  1 ANSI编码
  A.txt有四个字节:B1 E0 C2 EB。其中B1 E0是"编"的GBK编码,C2 EB是"码"的GBK编码。
  所以,记事本里的ANSI编码,对于简体中文操作系统而言,就是GBK编码。对于繁体中文操作系统而言,就是Big5编码……
  2 UTF16BE编码
  UB.txt有六个字节:FE FF 7F 16 78 01。其中FE FF是BOM(Byte Order Mark),暂时不用管它。0x7F16是"编"的Unicode编码,0x7801是"码"的Unicode编码。
  UTF16BE编码是16位(2字节)的Unicode编码,BE表示big endian,即高位字节在前,低位字节在后。Unicode编码0x7F16的高位字节是7F,低位字节是16,UTF16BE编码就是7F 16。
  3 UTF16LE编码
  U.txt有六个字节:FF FE 16 7F 01 78。其中FF FE是BOM,暂时不用管它。0x7F16是"编"的Unicode编码,0x7801是"码"的Unicode编码。
  UTF16LE编码是16位(2字节)的Unicode编码,LE表示little endian,即低位字节在前,高位字节在后。Unicode编码0x7F16的高位字节是7F,低位字节是16,UTF16LE编码就是16 7F。
  可见:UTF16LE与UTF16BE只是高低位字节交换了一下而已。
  4 UTF-8编码
  U8.txt有九个字节:EF BB BF E7 BC 96 E7 A0 81。其中EF BB BF是BOM,暂时不用管它。E7 BC 96是"编"的UTF-8编码,E7 A0 81是"码"的UTF-8编码。
  5 BOM
  BOM是Byte Order Mark的缩写,它用来指明编码,如下所示:

  BOM
  编码
  FE FF
  UTF16BE
  FF FE
  UTF16LE
  EF BB BF
  UTF-8
  上面的FE FF和FF FE正好逆序,这也就是Byte Order Mark(字节顺序标记)的来由吧。
  6 乱码
  记事本通过BOM来区分各种编码,为什么不给ANSI搞个BOM?原因在于——向下兼容。从DOS到Win98,文本文件都是ANSI编码,都没有BOM。为了能够顺利的打开这些文件,不能增加BOM。
  通过BOM来区分各种编码,是一个非常好的想法。不过,没有历史包袱的Linux不买账——Linux默认就使用UTF-8编码,而且是没有BOM的UTF-8编码。
  为了能够打开Linux生成的没有BOM的UTF-8编码文件,记事本在打开没有BOM的文本文件时,会对其进行检查。如果所有编码符合UTF-8,就以UTF-8编码打开。
  把图1中的"编码"替换为"联通",另存为ANSI编码。再次打开,显示如下图所示:
DSC0002.png

  图3
  使用VC++6.0打开这个文件,一切正常,如下图所示:
DSC0003.png

  图4
  记事本显示乱码,是因为它会把"联通"的GBK编码C1 AA CD A8当做UTF-8编码进行显示;VC++6.0没有显示乱码,是因为它不支持UTF-8编码,只支持ANSI编码。
  有哪些汉字的GBK码会被当做UTF-8编码呢?一段MFC代码就让它们原形毕露了:

  CFile f;
  if(f.Open(_T("W:\\1.txt"),CFile::modeCreate | CFile::modeWrite))
  {
   f.Write(":\r\n",4); //这句很重要,否则记事本打开后显示乱码
   int q = 0; //区码
   int w = 0; //位码
   int c = 0;
   BYTE n[2]; //内码
   for(q = 0x81;q <= 0xFE;++q)
   {
   n[0] = q;
   for(w = 0x40;w <= 0xFE;++w)
   {
   n[1] = w;
   if(n[0] >= 0xC0 && n[0] <= 0xDF
   && n[1] >= 0x80 && n[1] <= 0xBF)
   {
   f.Write(n,2);
   if(++c >= 40)
   {
   c = 0;
   f.Write("\r\n",2);
   }
   }
   }
   }
   f.Close();
  }
  运行结果如下:
DSC0004.png

  图5
  这样的汉字竟然有2048个。除了"联通"还有如下常见的汉字:

  乾坤、学习、史实、母女、孝顺、鲁莽、矛盾、沉默、诗词、脚趾、拇指、农忙、投石、泰山、水帘、矢量、粮食、太平、谦逊、尧舜、一十百千
  注意:上图第一行的全角冒号很重要,就是因为它的存在,记事本才不会误判编码为UTF-8,也就不会乱码显示了。类似的字符还有很多,如下所示:

  ,、:;""。!……——【】■□▲△◆◇○◎●★☆←↑→↓
  7 总结
  Windows下,文本文件有五种编码:ANSI、UTF16BE、UTF16LE、UTF-8有BOM、UTF-8无BOM(仅读取时支持该编码)。
  另存为ANSI编码时,因为没有BOM,所以有可能会被记事本、UltraEdit等文本编辑器当做无BOM的UTF-8编码,导致显示乱码。
  生成的文本文件除非要用于Win98,否则最好使用UTF-8编码保存。
  某些软件,如:Android Studio强制要求源代码文件使用无BOM的UTF-8编码。对于这类文件,可使用记事本查看,不要保存。否则前面三个字节的BOM(EF BB BF)删除起来还是比较麻烦的。
  为了方便的在这五种编码之间相互转换,可参考笔者的博文:
  http://blog.csdn.net/hanford/article/details/53351153

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-389039-1-1.html 上篇帖子: Windows ,获取硬盘物理序列号(VC++) 下篇帖子: autoitv3点击windows界面
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表