编码
- 计算机中存储信息的最小单元是一个字节,即8个bit,所以能表示的字符范围是0~255个
- 人类要表示的符号太多,无法用一个字节来完全表示
ASCII码
共有128个,用一个字节的低7位表示
- 0~31 控制字符 如换行、回车、删除
- 32~126 打印字符
ISO8859-1
在ASCII码的基础上涵盖了大多数西欧语言字符,仍然是单字节编码,它总共能表示256个字符
GB2312
全称为《信息交换用汉字编码字符集基本集》,它是双字节编码,总的编码范围是A1~F7
- A1~A9 ·符号区
- B0~F7 汉字区
GBK
全称《汉字内码扩展规范》,扩展了GB2312,加入更多的汉字,它的编码范围是8140~FEFE(去掉XX7F),与GB2312兼容
GB18030
《数字交换用汉字编码字符集》,它可能是单字节、双字节或者四字节编码,与GB2312编码兼容
UTF-16
具体定义了Unicode字符在计算机中的存取方法。采用2字节来表示Unicode转化格式,它是定长的表示方法,不论什么字符都可以用两个字节表示
UTF-8编码规则
UTF-8采用一种变长技术,每个编码区域有不同的字码长度,不同的字符可以由1~6个字节组成。
编码规则如下:
- 如果一个字节,最高位为0,表示这是一个ASCII字符(00~7F)
- 如果一个字节,以11开头,连续的1的个数暗示这个字符的字节数
如110xxxxx代表它是双字节UTF-8字符的首字母
- 如果一个字节,以10开始,表示它不是首字节,需要向前查找才能得到当前字符的首字节
如下:在一个文件中通过UTF-8编码,输入“中国”保存后,通过如下代码读取
File f = new File("F:/study/test/test.txt");
try {
FileInputStream input = new FileInputStream(f);
//BufferedReader reader = new BufferedReader(new InputStreamReader(input));
int i;
while((i=input.read())!=-1){
System.out.println(Integer.toBinaryString(i));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
输出
如下结果:
11100100
10111000
10101101
11100101
10011011
10111101
10111000
10101101
11100101
10011011
10111101
从中可以看出,这两个汉字均占用三个字节存储
字节-字符转变
String a = "中国";
Charset charset = Charset.forName("UTF-8");
ByteBuffer byteBuffer = charset.encode(a);
while(byteBuffer.hasRemaining()){
byte b = byteBuffer.get();
String s = Integer.toBinaryString((b & 0xFF) + 0x100).substring(1);
System.out.println(s);
}
如上所示,为byte获取其在内存中存储的二进制形式的方法。