字符输入流FileReader
操作本地文件的字符输入流
基本用法
- 创建字符输入流对象
| 构造方法 | 说明 |
|---|---|
| public FileReader(File file) | 创建字符输入流关联本地文件 |
| public FileReader(String pathname) | 创建字符输入流关联本地文件 |
- 读取数据
| 成员方法 | 说明 |
|---|---|
| public int read() | 读取数据,读到末尾返回-1 |
| public int read(char[] buffer) | 读取多个数据,读到末尾返回-1 |
- 释放资源
| 成员方法 | 说明 |
|---|---|
| public int close() | 释放资源/关流 |
细节
-
创建字符输入流对象
- 如果文件不存在,就直接报错
-
读取数据
- 按字节进行读取,遇到中文,一次读多个字节,读取后解码,返回一个整数
- 读到文件末尾了,read返回-1
-
释放资源
- 每次使用完流后都要释放资源
空参read方法细节
- 默认也是一个字节一个字节的读取的,如果遇到中文就会一次读取多个
- 在读取后,方法的底层还会进行解码并转成十进制,最终把这个十进制作为返回值
- 这个十进制的数据也表示字符在字符集上的数字
- 英文
- 文件里面的二进制数据:0110 0001
- read方法进行读取,解码并转成十进制97
- 中文
- 文件里面的二进制数据:11100110 10110001 10001001
- read方法进行读取,解码并转成十进制27721
- 英文
- 如果想看到中文汉字,就是把这些十进制数据再进行强转就行了
FileReader fr = new FileReader("myio\\a.txt");
int ch;
while ((ch = fr.read()) != -1) {
System.out.print(char(ch));
}
fr.close();
有参read方法细节
- 读取数据,解码,强转三步合并,把强转之后的字符放到数组当中
- 空参的read方法 + 强制类型转换
FileReader fr = new FileReader("myio\\a.txt");
char[] chars = new char[2];
int len;
while ((len = fr.read(chars)) != -1) {
System.out.print(new String(chars, 0, len));
}
fr.close();
底层原理
-
创建字符输入流对象
- 关联文件,并创建缓冲区(长度为8192的字节数组)
- 好处:减少了频繁到硬盘中读取数据的过程,提高效率
- 字节流没有缓冲区
-
读取数据
- 判断缓冲区中是否有数据可以读取
- 缓冲区没有数据
- 就从文件中获取数据,转到缓冲区中,每次尽可能装满缓冲区
- 如果文件中也没有数据了,返回-1
- 缓冲区有数据
- 就从缓冲区中读取
- 空参的read方法:一次读取一个字节,遇到中文一次读多个字节,把字节解码并转成十进制返回
- 有参的read方法:把读取字节,解码,强转三步合并了,强转之后的字符放到数组中
- 缓冲区没有数据
- 判断缓冲区中是否有数据可以读取
-
第二次从文件中读取数据转移到缓冲区中时,缓冲区中的数据不会先被清空再填入,而是会被逐个覆盖,因此缓冲区中多出来的部分并不会被清空
-
看下面这段代码
FileReader fr = new FileReader("myio\\b.txt");
fr.read();//将数据放到缓冲区中
//清空文件
FileWriter fw = new FileWriter("myio\\b.txt");
//文件此时已经被清空,请问这时再使用fr进行读取,会读取到数据吗?
//会把缓冲区中的数据全部读取完毕
//因此只能读取缓冲区中的数据,文件中剩余的数据无法再次读取
int ch;
while((ch = fr.read()) != -1) {
System.out.println(char(ch));
}
fw.close();
fr.close();