Java学习-IO流-字符集
FileInputStream fis = new FileInputStream("...\\xx.txt");
int b;
while((b=fis.read())!=-1){sout((char)b);}//→ 乱码
fis.close();
分析原因:
计算机中任意数据以二进制形式存储
最小的存储单元:字节
英文:一个字节
ASCII:英文
GBK:英文\中文
Unicode:英文\中文
ASCII字符集
0~127共128个字符,每个字符占用一个字节
‘a’ → 97 → 110 0001 → 0110 0001
0110 0001 → 97 → ‘a’
GB2312
1.GB2312字符集:1980年发布,收录7445个图形字符,包括6763个简体汉字
2.BIG5字符集:台湾地区繁体中文标准字符集,收录13053个中文字符
3.GBK字符集:收录21003个汉字,包含GB12000-1中的全部中日韩汉字和BIG5中所有汉字
Windows系统默认使用GBK,系统显示ANSI
4.Unicode字符集:国际标准字符集
GBK存储
英文:‘a’ → 97 → 110 0001 → 0110 0001
汉字:‘汉’ → 47802 → 10111010 10111010
规则1:汉字使用两个字节存储
规则2:英文一个字节存储,兼容ASCII,二进制前补0;汉字高位字节二进制一定以1开头,转成十进制是一个负数
例:10111010 10111010 01100001 中有几个汉字几个英文
答:第一个字节 10111010 以1开头,前两个字节是汉字,第三个字节 01100001 以0开头,是英文,共1个汉字1个英文:汉a
例:01100001 01100010 01100011
答:3个英文:abc
例:10110000 10101110 11001110 11010010 11010110 11010000 10111011 10101010
答:4个汉字:爱我中华
总结
1.计算机中数据以二进制形式存储
2.最小存储单元是字节
3.ASCII字符集中一个英文占一个字节
4.简体Windows默认使用GBK字符集
5.GBK字符集完全兼容ASCII字符集,一个英文占一个字节,二进制第一位都是0;一个汉字占两个字节,二进制高位字节第一位都是1
Unicode字符集
UTF-8:加粗:固定格式,x:Unicode码填补
英文:一个字节,0xxxxxxx
汉字:三个字节,1110xxxx 10xxxxxx 10xxxxxx
‘a’ → 97 → 1100001 → 01100001
‘汉’ → 27721 → 01101100 01001001 → 11100110 10110001 10001001
UTF-8是字符集吗?
不是字符集,而是Unicode字符集的一种编码方式
例:01001010 01100001 01110110 01100001
答:4个英文:Java
例:01100001 01101001 11100100 10111101 10100000 11100101 10010011 10011111
答:2个英文2个汉字:ai你呦
总结
1.Unicode字符集的UTF-8编码格式,一个英文占一个字节,二进制第一位是0;一个汉字占三个字节,二进制第一位是1
为什么会有乱码?
原因1.读取数据时未读完整个汉字
原因2.编码和解码方式不一致
如何不产生乱码?
1.不要用字节流读取文本文件
2.编码解码使用同一个码表,同一个编码方式
编码和解码的代码实现
public byte[] getBytes():使用默认方式解码
public byte[] getBytes(String charsetName):使用指定方式编码
String(byte[] bytes):使用默认方式解码
String(byte[] bytes,String charsetName):使用指定方式解码
String str1 = "IO流";
byte[] bytes1 = str1.getBytes();
sout(Arrays.toString(bytes1));//→ [73,79,-26,-75,-127]
String str2 = "IO流";
byte[] bytes2 = str2.getBytes(GBK);
sout(Arrays.toString(bytes2));//→ [73,79,-63,-9]
String str3 = new String(bytes1);
sout(str3);//→ IO流
String str4 = new String(bytes2,"GBK");
sout(str4);//→ IO流
String str5 = new String(bytes1,"GBK");
sout(str5);//→ IO娴?