Java Stream BufferedReader文件流

Mah*_*lam 2 bufferedreader java-8 java-stream

我正在使用Java 8 Streams从csv文件创建流.我正在使用BufferedReader.lines(),我阅读了以下文档BufferedReader.lines():

在执行终端流操作之后,不能保证读取器将处于从中读取下一个字符或行的特定位置.

public class Streamy {
    public static void main(String args[]) {
        Reader reader = null;
        BufferedReader breader = null;
        try {
            reader = new FileReader("refined.csv");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        breader = new BufferedReader(reader);
        long l1 = breader.lines().count();
        System.out.println("Line Count " + l1); // this works correctly

        long l2 = breader.lines().count();
        System.out.println("Line Count " + l2); // this gives 0
    }
}
Run Code Online (Sandbox Code Playgroud)

它看起来像是第一次读取文件后,读者无法进入文件的开头.解决这个问题的方法是什么?

Jon*_*eet 8

它看起来像是第一次读取文件后,读者无法进入文件的开头.

不 - 而且我不知道为什么你会期望它给你引用的文件.基本上,该lines()方法在开始之前不会"回放"阅读器,甚至可能无法.(想象一下BufferedReader包装InputStreamReader网络连接的包装InputStream- 一旦你读完了数据,它就消失了.)

解决这个问题的方法是什么?

两种选择:

  • 重新打开文件并从头开始阅读
  • 将结果保存lines()到a List<String>,以便您第二次不读取文件.例如:

    List<String> lines = breader.lines().collect(Collectors.toList());
    
    Run Code Online (Sandbox Code Playgroud)

顺便说一句,我强烈建议使用Files.newBufferedReader而不是FileReader- 后者总是使用平台默认编码,这通常不是一个好主意.

就此而言,要将所有行加载到列表中,您可以使用Files.readAllLines...或者Files.lines如果您希望将行作为流而不是列表.(但请注意评论中的警告.)