Java 尝试使用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

我试图使用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对象更好呢?

您可以按行读取,如下所示

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,或者其他任何流。。。