本文介绍字符输入流
在前面一节中,我们向一个文件中写入了一些字符,通过图片可以看出总共是6个中文字符和一个换行,总共是20个字节,可以推算出字符编码是utf-8,每个汉子占3三个字节。本文就用字符输入流来读一下。
代码部分
package io.charStream;
import java.io.FileInputStream;
import java.io.FileReader;
/**
* @Author: micro cloud fly
* @Description: 字符流学习-FileReader
* @Date: Created in 10:20 上午 2020/10/20
*/
public class Demo1 {
public static void main(String[] args) throws Exception {
//文件内容为Abcdefg,当文件中有中文时,utf-8编码的每个中文占三个字节,那么每个字节读取的时候打印出来就是乱码了
FileInputStream inputStream = new FileInputStream("/Users/java0904/Pictures/imgs/1.txt");
//int count = 0;
打印
//while((count=inputStream.read())!=-1){
// System.out.println((char)count);
//}
文件内容为:希望你开心hah234,打印出来的是一片乱码
//inputStream = new FileInputStream("/Users/java0904/Pictures/imgs/2.txt");
//count = 0;
打印
//while((count=inputStream.read())!=-1){
// System.out.println((char)count);
//}
//改为用字符流进行读取,filereader内部做了编码的确认工作,即使有中文也有英文,读取也不会乱码,是不是很神奇
FileReader fileReader = new FileReader("/Users/java0904/Pictures/imgs/filewriter.txt");
//int count = 0;
//while ((count = fileReader.read()) != -1) {
// System.out.println((char) count);
//}
//也可以一次读取多个
int count = 0;
char[] cbuf = new char[1];
while ((count = fileReader.read(cbuf)) != -1) {
System.out.println("count:"+ count +", "+new String(cbuf, 0, count));
}
System.out.println("----");
}
}
输出
count:1, 你
count:1, 好
count:1,
count:1,
count:1, 我
count:1, 是
count:1, 小
count:1, 微
----
问题
以下这段代码需要格外注意下
int count = 0;
char[] cbuf = new char[1];
while ((count = fileReader.read(cbuf)) != -1) {
System.out.println("count:"+ count +", "+new String(cbuf, 0, count));
}
我们都知道java中char类型占用2个字节,而文件中的中文是占用3个字节,那么为什么一个2字节的char数组,可以装入3字节的汉字呢?
这其中一定是java搞的鬼了。
原因
java 是采用Unicode编码,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。通常Unicode占用两字节,也就说Unicode用两字节就能表示世界上全部语言。UTF-8(是针对Unicode的一种可变长度字符编码。重点是“可变”,UTF-8根据存储的字符类型不一样,他所占的字节是不一样的,例如,英文时,只占用1个字节,中文时则膨胀为3个字节。
编译后生成的class文件会把汉字转化成Unicode的两字节,也就说Java内部或者说Jvm内部对字符的编码计算基于Unicode双字节,而外部显示存储则是用UTF-8,通过这种方式从而实现两字节的Char存储UTF-8编码的字符。