[英]infinite loop occurs when trying to read a file with FileReader object
我试图使用 FileReader 从文件中读取,但程序进入无限循环:这是我的代码:
import java.io.FileReader;
public class Test {
public static void main(String[] args) {
try(FileReader f = new FileReader("sales.dat");){
char ch = (char)f.read();
while(ch != -1){
ch = (char)f.read();
System.out.print(ch);
}
}catch (Exception e){
}
}
}
为什么只使用 FileReader 读取文件效率不高,而最好使用 BufferedReader 对象
char 的范围在0
到65535
之间,因此它不能为-1
因此char != -1
始终为真。
while(int ch; (ch = f.read()) >= 0;)
System.out.print((char) ch);
这将在转换为char
之前检查值是否为非负
为什么仅使用 FileReader 读取文件效率不高,而最好使用 BufferedReader 对象
BufferedReader 使用 FileReader 所以也许问题应该是; 为什么不单独使用 FileReader?
答案是; 调用操作系统是昂贵的。 每次调用可能是几微秒,而进程内存访问可能是纳秒。
通过使用缓冲区,例如 BufferedReader,您调用操作系统的次数要少得多(默认情况下最多为 1/8192),这提高了获取每个字节数据的效率。
在上面的例子中,这并不重要。 虽然调用 FileReader 很昂贵,但与写入控制台相比,它很便宜。 写入控制台是这里唯一影响性能的事情。
相反,您可以像这样逐行阅读
final File file = new File("your_file");
try (final InputStream fileStream = new FileInputStream(file.getAbsolutePath()); final Reader decoder = new InputStreamReader(fileStream);
final BufferedReader buffered = new BufferedReader(decoder)) {
String line;
while ((line = buffered.readLine()) != null) {
// do stuff
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
附: 不知道你的子问题
您无法获得负的 char 值,因此小于 -1 的检查将始终为假。
使用子类InputStreamReader
,您应该依靠ready()
来检查您是否已到达流的末尾。
while(reader.ready()){
// do stuff
}
使用缓冲流更快,因为它减少了操作系统 IO 调用的数量。 如果您有一个 100 万字节的文件并一次读取一个字节,对于每个非缓冲调用,JVM 需要从操作系统请求读取。 这是 Java 进程请求从操作系统读取的 100 万次。 对于缓冲流,它尝试在一次读取中填充其缓冲区。 因此,即使您请求 1 个字节,底层流在内存中也会有 N 个字节,从而将底层操作系统的调用次数减少大约 FILE_SIZE/BUFFER_SIZE。 对于 1 MB 的文件,如果缓冲区大小为 1024,并且每次都能填满,则 OS 调用数将为 1M/1K,即 1000 次读取 vs 100 万次。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.