目录

1 ANSI编码    2

2 UTF16BE编码    2

3 UTF16LE编码    2

4 UTF-8编码    2

5 BOM    3

6 乱码    3

7 总结    5

如下图所示,在记事本里输入"编码",然后另存为的时候,有四种编码:

图1

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

编码

文件名

ANSI

A.txt

Unicode

U.txt

Unicode big endian

UB.txt

UTF-8

U8.txt

使用VC++6.0或Visual Studio以二进制方式打开这四个文件。二进制编码一目了然,如下图所示:

图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编码。再次打开,显示如下图所示:

图3

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

图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();

}

运行结果如下:

图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

Windows文本文件编码的更多相关文章

  1. unity开发相关环境(vs、MonoDevelop)windows平台编码问题

    情景描述:最近在做Unity的网络底层,用VS编写源码,MonoDevelop用来Debug,在Flash Builder上搭建的Python做协议生成器,期间有无数次Unity莫名奇妙的的down掉 ...

  2. 签名、BOM头、编码、Windows记事本编码、java编码解码的那些事

    对于Windows记事本: ANSI :GB2312 java中应使用GBK解码 Unicode :有签名的UTF-16LE java中应使用UTF-16解码 Unicode big endian : ...

  3. (转)unity开发相关环境(vs、MonoDevelop)windows平台编码问题

    转自: http://www.cnblogs.com/sevenyuan/archive/2012/12/06/2805114.html 1.unity会爆出错误: There are inconsi ...

  4. 【笨嘴拙舌WINDOWS】编码历史

    在介绍历史之前,有必要将一个经常使用的词语"标准"解释一下: " 标准是"为了在一定的范围内获得最佳秩序,经协商一致制定并由公认机构批准,共同使用的和重复使用的 ...

  5. Fedora中显示windows下的文件

    目录 一些预备知识: 在中国windows的编码是本地编码 , 即GBK,GB2312,GB18030等 GBK  也就是windows-986 Windows现在只支持Unicode (UTF-16 ...

  6. 【转】Gvim开发环境配置笔记--Windows篇

    配置文件(vimrc) set nocompatible set nu! set cursorline colorscheme murphy " vim 自身命令行模式智能补全 set wi ...

  7. Java用native2ascii命令做unicode编码转换

    背景:在做Java开发的时候,常常会出现一些乱码,或者无法正确识别或读取的文件,比如常见的validator验证用的消息资源(properties)文件就需要进行Unicode重新编码.原因是java ...

  8. jenkins使用git SCM时changelog乱码(Jenkins部署在Linux上,任务在Windows Slave上构建)

    问题原因 changelog的获取方式(git-client插件): 首先调用git whatchanged命令,读取输出字节流(UTF-8编码的Commit Message). 将字节流解码为字符串 ...

  9. mac 文本编辑器 文本编码Unicode utf-8 不适用的问题

    在mac上使用默认的文本编辑器打开下载的xx.txt文件,如果文本是gbk的编码可能会出现 文本编码Unicode utf-8 不适用的打开错误,如下图 解决方式: 文本编辑---偏好设置-----打 ...

随机推荐

  1. ionic使用方法

    windows下安装配置 npm install -g ionic npm install -g cordova ionic start myproject cd myproject ionic pl ...

  2. InnoDB VS MyISAM

    首先都是MySql存储引擎.数据库的考虑点一般就是事务(ACID),然后牵扯出的锁机制.如果你需要事务,那就只能选InnoDB了.如果你还需要外键约束,你也只能选择InnoDB.这个是两者最大的区别. ...

  3. zabbix-agent配置文件说明

    zabbix-agent配置文件:/etc/zabbix/zabbix_agentd.conf Server=zabbix server IP,网关IP hostname=本机IP ServerAct ...

  4. Java String.split()小点

    java String.split(); 别的不说,单说其中一个问题,这个函数去切分空字符串时,得到的结果: public static void main(String[] args) {// St ...

  5. winform中button点击后再点击其他控件致使button失去焦点,此时button出现黑色边线,去掉黑色边线的方法

    winform中button点击后再点击其他控件致使button失去焦点,此时button出现黑色边线,去掉黑色边线的方法 button的FlatAppearence属性下,设置BorderSize= ...

  6. 在网页中嵌入地图API

    1.登录百度地图api,地址:http://api.map.baidu.com/lbsapi/creatmap/index.html 2.设置你的地理位置 3.简单设置下地图功能.地图的宽度和高度根据 ...

  7. javascript日期验证:填写的日期大于等于当前日期

    <script> $(function () { var d = new Date(); var strDate = getDateStr(d); $("#beginTime&q ...

  8. HTML 学习笔记 CSS(选择器)

    CSS元素选择器 最常见的CSS 选择器就是元素选择器 换句话说 文档的元素就是最基本的选择器 如果设置HTML样式 选择器通常就是某个HTML元素 比如p h1 em a 甚至可以是HTML本身 h ...

  9. 黑马程序员_JAVA之交通灯管理系统

    ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 1.一.需求:模拟实现十字路口的交通灯管理系统逻辑,具体需求如下:  1.异步随机生成按照各个路 ...

  10. SQLAlchemy 中文文档翻译计划

    SQLAlchemy 中文文档翻译计划已启动. Python 文档协作翻译小组人手紧缺,有兴趣的朋友可以加入我们,完全公益性质.交流群:467338606. 希望大家能够勇敢地去翻译和改进翻译.虽然我 ...