@import url(http://www.cppblog.com/cutesoft_client/cuteeditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);
最低位地址存放高位字节,可称高位优先,内存从最低地址开始按顺序存放(高数位数字先写)。最高位字节放最前面。
例如“汉”字的Unicode编码是6C49。如果将6C写在前面,就是big endian。还是将49写在前面,就是little endian
Endian可读为字节序.
0x11BB,高字节为11,低字节为BB
Big Endian: 高字节存储在高位,低字节存储在低位: 高字节结束存储: BB 11
Little Endian: 高字节存储在低位,低字节存储在高位: 低字节结束存储: 11 BB
数字的高低位与存储中位置偏移的高低位正好相反. Little Endian更适合阅读,因为11BB存储为11BB.
import java.nio.ByteOrder;
public class Test {
public static void main(String[] args) {
char c = '\u11BB';
String endian = Integer.toHexString(c & 0xFF).toUpperCase();
System.out.println(endian.equals("BB") ? "Little Endian" : "Big Endian");
System.out.println(ByteOrder.nativeOrder());
}
}
BOM(字节序标志): Byte Order Mark
UTF-16是以两个字节为编码单元,要考虑字节序,所以使用BOM来标志字节序: FEFF or FFFE.
FEFF 又叫做 Zero Witdh No-Break Space,它在UCS中是不存在的字符,所以用来标志字节序,又称做BOM.
FEFF: Big Endian
FFEF: Little Endian
A: The following table summarizes some of the properties of each of the UTFs.
Name | UTF-8 | UTF-16 | UTF-16BE | UTF-16LE | UTF-32 | UTF-32BE | UTF-32LE |
Smallest code point |
0000 |
0000 |
0000 |
0000 |
0000 |
0000 |
0000 |
Largest code point |
10FFFF |
10FFFF |
10FFFF |
10FFFF |
10FFFF |
10FFFF |
10FFFF |
Code unit size |
8 bits |
16 bits |
16 bits |
16 bits |
32 bits |
32 bits |
32 bits |
Byte order |
N/A |
<BOM> |
big-endian |
little-endian |
<BOM> |
big-endian |
little-endian |
Fewest bytes per character |
1 |
2 |
2 |
2 |
4 |
4 |
4 |
Most bytes per character |
4 |
4 |
4 |
4 |
4 |
4 |
4 |
Windows保存的Unicode文件是含有BOM的,UTF-8编码的文件以字节为编码单元,不存在字节序的问题,但可以使用BOM来表示编码方式: 文件前3字节是EF BB BF,为UTF-8编码。因为FEFF在UTF-8里的编码为EF BB BF.
Mac下的TextEdit保存为UTF-8就不含BOM
TextWrangler可以选择是否包含有BOM
一个汉字在Unicode中用两个字节表示,a-z等字母也是两个字节。
UTF-8是Unicode的一种表现形式(Unicode编码值使用UTF-8方式编码存储),是一种变长的表达方式,把字符的Unicode编码在文件中表现出来,从一个字节到三个字节不等(为了减少如a-z等ascii码字符占用的空间,因为他们出现太频繁了).
UTF-8编码范围为:
0000 - 007F : 0xxxxxxx
0080 - 07FF : 110xxxxx 10xxxxxx
0800 - FFFF : 1110xxxx 10xxxxxx 10xxxxxx
如"汉"的Unicode编码为6C49,在0800 - FFFF之间,所以要使用3字节模板: 1110xxxx 10xxxxxx 10xxxxxx
6C49的二进制是: 0110 110001 001001
用这个二进制流依次代替3字节模板中的x得: 1110 0110 10110001 10001001,即E6 B1 89
保存到文件中的就是3个字节E6 B1 89,而不是2个字节6C 49
// 给InputStreamReader指定要读取的文件的编码,读取时就不会出现乱码了.
public class TextFileReader {
public static void main(String[] args) throws Exception {
String filename = "source/demo-gb18030.txt";
String encoding = "gb18030";
printFile(filename, encoding);
}
// 打印出文件的文本内容, 使用指定的编码读入文件
public static void printFile(String filename, String encoding) throws IOException {
InputStreamReader isr = new InputStreamReader(new FileInputStream(filename), encoding);
BufferedReader reader = new BufferedReader(isr);
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
}