Java FileReader

387 阅读3分钟

字符输入流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();