Java中Scanner与FileReader构造传参的底层交互原理
Scanner与FileReader交互的底层逻辑
对应问题中的示例代码如下:
try{ PrintWriter pW = new PrintWriter("newFile.txt"); pW.println("Hello"); pW.print("My name is Julian"); pW.println(""); pW.print("This is the third line"); pW.close(); FileReader fR = new FileReader("newFile.txt"); Scanner scan = new Scanner(fR); System.out.println(scan.nextLine()); System.out.println(scan.nextLine()); System.out.println(scan.nextLine()); }catch(Exception ex){ }
对你的猜想的答复
你对运行逻辑的概念化理解基本完全正确,对照JDK源码的标准实现,有几个具体细节可以补充:
- 调用
new Scanner(fR)传入FileReader实例时,Scanner不会立刻触发文件读取操作,只会把传入的FileReader实例保存为内部的源引用,同时初始化一个默认长度为1024的char[]类型内部缓冲区。 - 第一次调用
nextLine()、next()或者其他取值方法时,Scanner才会触发实际的磁盘IO:它会直接调用绑定的FileReader的read(char[] buffer, int offset, int length)方法,把自身的内部字符缓冲区作为参数传入,让FileReader把文件中的字符批量读入这个数组——这个过程和你手动调用FileReader的read方法读取字符数组的逻辑没有本质区别。 - 数据加载到缓冲区后,Scanner不会每次调用取值方法都重新读取文件:
- 它会先在当前缓冲区的可读范围内扫描对应分隔符,
nextLine()使用的分隔符是换行符,会自动兼容\n和\r\n两种换行格式 - 如果当前缓冲区里已经包含完整的目标内容,就直接移动缓冲区的读指针,截取对应位置的字符返回,这个过程不会触发额外IO
- 如果缓冲区剩余内容不足(比如扫完所有已读字符都没找到换行符、或者没读够匹配的token长度),Scanner会再次调用FileReader的read方法往缓冲区填充新的字符,直到拿到足够的返回内容、或者读到文件末尾为止
- 它会先在当前缓冲区的可读范围内扫描对应分隔符,
- 缓冲区的内容是顺序消费的,已经读过的内容不会重复保留,因此连续调用
nextLine()会按照文件内字符的存储顺序逐行返回结果。
示例代码运行结果
你这段代码实际写入文件的内容共3行,三次nextLine()调用会依次在控制台输出:
Hello My name is Julian This is the third line
内容的提问来源于stack exchange,提问作者Julian Biju
相关产品推荐
相关产品推荐

