Java 尝试使用FileReader对象读取文件时发生无限循环
我试图使用FileReader读取文件,但程序进入无限循环:以下是我的代码:Java 尝试使用FileReader对象读取文件时发生无限循环,java,Java,我试图使用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
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对象更好呢?您可以按行读取,如下所示
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();
}
注:不知道你的子问题字符的范围在
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的成本很高,但与写入控制台相比,它的成本很低。写入控制台是这里唯一对性能有影响的事情。您不能得到一个负的char值,因此小于-1的检查总是错误的 当使用子类InputStreamReader时,您应该依靠检查是否已到达流的末尾
while(reader.ready()){
// do stuff
}
使用缓冲流更快,因为它减少了操作系统IO调用的数量。如果您有一个100万字节的文件,并且一次读取一个字节,那么对于每个非缓冲调用,JVM需要从操作系统请求读取。这是Java进程请求从操作系统读取的100万倍。对于缓冲流,它尝试在一次读取中填充其缓冲区。因此,即使您请求1个字节,底层流的内存中也会有N个字节,从而将底层操作系统的调用数量减少大约文件大小/缓冲区大小。对于1MB文件,如果缓冲区大小为1024,并且每次都可以填充,则操作系统调用的数量将为1M/1K,即1000次读取vs 100万次读取 将read()值强制转换为char,然后将该char与int进行比较。。。没有“负字符”之类的东西。@Marc B将此添加为答案。检查@Marc B谢谢我修复了它。这是非常好的解释,非常感谢,我完全不明白为什么BufferedReader能够高效地use@KhatabBouchra不客气。如果答案对你有帮助,通常习惯上会投赞成票。我很想投赞成票,但我没有足够的声望点数来投票,所以一旦我达到这些点数,我会投赞成票:)你需要从某个地方开始,我使用这个代码来阅读。。。BufferedReader(和其他东西)的优点是,您可以给它一个zipStream,或者其他任何流。。。