首先看一下下面的程序(测试英文和中文在Unicode、UTF-8、UTF-16这三种编码下,一个字符占几个字节)
System.out.println("a(Unicode) :" + "a".getBytes("Unicode").length);
System.out.println("a(Unicode) :" + "aa".getBytes("Unicode").length);
System.out.println("啊(Unicode) :" + "啊".getBytes("Unicode").length);
System.out.println("啊啊(Unicode) :" + "啊啊".getBytes("Unicode").length);
System.out.println("");
System.out.println("a(UTF-8) :" + "a".getBytes("UTF-8").length);
System.out.println("aa(UTF-8) :" + "aa".getBytes("UTF-8").length);
System.out.println("啊(UTF-8) :" + "啊".getBytes("UTF-8").length);
System.out.println("啊啊(UTF-8) :" + "啊啊".getBytes("UTF-8").length);
System.out.println("");
System.out.println("a(UTF-16) :" + "a".getBytes("UTF-16").length);
System.out.println("aa(UTF-16) :" + "aa".getBytes("UTF-16").length);
System.out.println("啊(UTF-16) :" + "啊".getBytes("UTF-16").length);
System.out.println("啊啊(UTF-16) :" + "啊啊".getBytes("UTF-16").length);
运行结果如下:
a(Unicode) :4
a(Unicode) :6
啊(Unicode) :4
啊啊(Unicode) :6
a(UTF-8) :1
aa(UTF-8) :2
啊(UTF-8) :3
啊啊(UTF-8) :6
a(UTF-16) :4
aa(UTF-16) :6
啊(UTF-16) :4
啊啊(UTF-16) :6
可以看到UTF-8的情况:一个英文字符占一个字节,一个汉字占三个字节
但是Unicode和UTF-16的情况比较奇怪,不管是英文还是汉字,看不出占几个字节。其实正确的答案是:Unicode和UTF-16的编码下,不管是英文字符还是汉字字符,都占两个字节(至于上面结果中多出来的两个字节是用来表示字节顺序的默认字节)。至于为什么,继续往下看。
Unicode规范中推荐的标记字节顺序的方法是BOM。BOM不是“Bill Of Material”的BOM表,而是Byte Order Mark。
(Unicode是一种字符编码方法,不过它是由国际组织设计,可以容纳全世界所有语言文字的编码方案。Unicode的学名是"Universal Multiple-Octet Coded Character Set",简称为UCS。UCS可以看作是"Unicode Character Set"的缩写。)
在UCS编码中有一个叫做"ZERO WIDTH NO-BREAK SPACE"的字符,它的编码是FEFF。而FFFE在UCS中是不存在的字符,所以不应该出现在实际传输中。UCS规范建议在传输字节流前,先传输字符"ZERO WIDTH NO-BREAK SPACE"。
这样如果接收者收到FEFF,就表明这个字节流是Big-Endian的;如果收到FFFE,就表明这个字节流是Little-Endian的。因此字符"ZERO WIDTH NO-BREAK SPACE"又被称作BOM。
在 Java 中直接使用Unicode 转码时会按照UTF-16LE 的方式拆分,并加上 BOM。 如果采用 UTF-16 拆分,在 Java 中默认采用带有 BOM 的 UTF-16BE 拆分。
再来看一个程序:
public class Test {
private final static char[] HEX = "0123456789abcdef".toCharArray();
public static void main(String[] args) throws UnsupportedEncodingException {
String str = "中国";
String[] encoding = { "Unicode", "UnicodeBig", "UnicodeLittle", "UnicodeBigUnmarked",
"UnicodeLittleUnmarked", "UTF-16", "UTF-16BE", "UTF-16LE" };
for (int i = 0; i < encoding.length; i++) {
System.out
.printf("%-22s %s%n", encoding[i], bytes2HexString(str.getBytes(encoding[i])));
}
}
public static String bytes2HexString(byte[] bys) {
char[] chs = new char[bys.length * 2 + bys.length - 1];
for (int i = 0, offset = 0; i < bys.length; i++) {
if (i > 0) {
chs[offset++] = ' ';
}
chs[offset++] = HEX[bys[i] >> 4 & 0xf];
chs[offset++] = HEX[bys[i] & 0xf];
}
return new String(chs);
}
}
运行结果如下:
Unicode fe ff 4e 2d 56 fd
UnicodeBig fe ff 4e 2d 56 fd
UnicodeLittle ff fe 2d 4e fd 56
UnicodeBigUnmarked 4e 2d 56 fd
UnicodeLittleUnmarked 2d 4e fd 56
UTF-16 fe ff 4e 2d 56 fd
UTF-16BE 4e 2d 56 fd
UTF-16LE 2d 4e fd 56
可以看到几个不同的Unicode和UTF-16编码的字节顺序是不同的,有的是fe ff,有的是ff fe,有的没有。
总上所述:
Unicode和UTF-16:1个字符占2个字节(不管是哪国语言)
UTF-8:1个英文字符占1个字节,一个汉字(包括日文和韩文等)占3个字节
Java中的char默认采用Unicode编码,所以Java中char占2个字节
另外,顺便提一个知识点:1个字节(byte)占8位(bit)
分享到:
相关推荐
不需要关心接受的字符串编码是UTF_8还是GBK,还是ios-8859-1,自动转换为utf-8编码格式,无需判断字符串原有编码,用法://处理编码String newStr = GetEncode.transcode(oldStr);
Java字符串编码查询及转换,可将常用的一些编码格式转换成utf-8
utf-8 unicode gb2312 汉字编码
最近需要对Linux与Windows平台下的字符传输出现乱码,对...参考了网上的UTF-8/UTF-16转换的资料,只有0x10000以下的Unicode编码进行了转换;对其代码进行了修改和补充,可以实现所有的UTF-8/UTF-16的转换,分享给大家。
unicode -> utf-8 utf-8 -> unicode 国际化必备工具
请使用这款软件,直接将代码转换为UTF-8 注意: 1、xml不需要转换,因为xml默认是utf-8,在你新建的时候已经是正确的格式了 2、图片更不需要转换 3、bin目录,gen目录的直接忽略 4.只需要src目录的代码转换,请确保...
GB2312编码与utf-8编码的字符串的转换,主要使用windows api函数MultiByteToWideChar和WideCharToMultiByte,代码简洁,经测试可用
此文本文档是UTF-8字符集中汉字编码对照表,可以用于查看某个汉字在UTF-8编码集中的位置。此编码集对照表非官网下载,如需使用,请提前预估风险。另外,此对照表只用于学习研究,如需用到其他地方,后果自负。
将UNICODE字符集与UTF-8字符集相互转换
php 字符编码转换类,支持ANSI、Unicode、Unicode big endian、UTF-8、UTF-8+Bom 互相转换。
Java解决UTF-8的BOM问题,使用“UnicodeInputStream”、“UnicodeReader”。
如果UNICODE字符由2个字节表示,则编码成UTF-8很可能需要3个字节,而如果UNICODE字符由4个字节表示,则编码成UTF-8可能需要6个字节。用4个或6个字节去编码一个UNICODE字符可能太多了,但很少会遇到那样的UNICODE...
字符编码笔记:ASCII-Unicode和UTF-8 字符编码笔记:ASCII-Unicode和UTF-8 字符编码笔记:ASCII-Unicode和UTF-8
UTF-16汉字编码表,txt格式的
在eclispe的项目中,有存在项目字符集和工作空间字符集不匹配,该jar只能将项目文件中的.java结尾的文件转为utf8编码,并且源文件必须为gbk编码的,否则乱码
为大家提供Python的UTF-8编码查询表,大家可以对照左列的编码查询右列的汉字。 例:\u4e00对应汉字“一”
由于项目需要,需要字符串转为XML文件,直接用Fileopen进行EncodingUTF8编码后,发现文件实际为UTF-8 BOM编码 问度娘发现有相同问题,但解决方式是利用新建一个UTF-8的TXT文件后,再进行COPY加内容。感觉这样操作...
批量转换文件编码格式为UTF-8工具.zip 支持多层文件夹替换! 使用说明: 1.文件根目录:即您要转码的文件所在根目录 2.转码文件目录:即您转码后的文件所在目录 3.转码文件后缀:指[文件根目录]下,需要转码的文件后缀,...
[字符集]Unicode和UTF-8之间的转换详解
关于JAVA字符编码:Unicode,ISO-8859-1,GBK,UTF-8编码及相互转换