【问题标题】:How to read a file line by line with Java Stream如何使用 Java Stream 逐行读取文件
【发布时间】:2018-11-19 12:00:01
【问题描述】:

我正在尝试逐行读取一个长文件,同时尝试从该行中提取一些信息。

这里是我正在做的一个例子:

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.stream.Stream;

public class ReadFile_Files_Lines {

    public static void main(String[] pArgs) throws IOException {
        String fileName = "c:\\temp\\sample-1GB.txt";
        File file = new File(fileName);

        try (Stream<String> linesStream = Files.lines(file.toPath())) {
            linesStream.forEach(line -> {
                System.out.println(line);
            });
        }
    }
}

我的文件中的一行分为三个部分:

10 1010101 15

我希望每次都阅读这三个信息。 喜欢:

String str1 = line[0];
String str2 = line[1];
String str3 = line[2];

如果我不应该将流转换为集合,我正在寻找的解决方案会更好。 我将使用这 3 个字符串来创建图形数据结构,例如:

createGraphe(str1,str2,str3);`

我知道我可以发送完整的字符串,但在学习 Stream 时,我很想知道如何提取这些信息。

谢谢。

【问题讨论】:

  • 你的问题我不清楚。你想用这三个元素做什么?如果您不想,请不要存储它
  • Files.readAllLines(Paths.get("c:\\temp\\sample-1GB.txt"))String.split(" "); 结合起来获得单行的值怎么样?
  • @deHaar 这会影响将完整文件内容加载到内存中。
  • @user7 我知道...也许没那么多... ;-) long 这个词并不是很具体。但是,是的,可能会有更好的想法。
  • @deHaar 从文件名来看,我猜大约 1GB ;)

标签: java string java-8 java-stream


【解决方案1】:

你可以通过分割每一行来映射到一个数组,然后调用你想要的方法。

Files.lines(filePath)
    .map(l -> l.split(" "))
    .forEach(a -> createGraphe(a[0], a[1], a[2]));

【讨论】:

  • 谢谢。这就是我正在寻找的,溢出的方法。您能否确认此解决方案比将流转换为字符串集合更好。
  • @zakzak 这取决于您的图形创建函数的外观,但我想它更好,因为它不必存储中间 String
【解决方案2】:

您正在使用的方法lines() 已经完成了您期望的操作。

Java 8 在 Files 类中添加了一个名为 lines() 的新方法,可用于在 Java 中逐行读取文件。这种方法的美妙之处在于它将文件中的所有行作为字符串流读取,当流被消耗时,它会延迟填充。因此,如果您有一个巨大的文件并且您只读取了前 100 行,那么其余的行将不会加载到内存中,这会带来更好的性能。

这与Files.readAllLines() 方法(将所有行读取到列表中)略有不同,因为此方法延迟读取文件,仅当在 Stream 上调用终端操作时,例如forEach()count() 等。通过使用count() 方法,您实际上可以通过过滤空行来计算文件中的行数或空行数。

参考:https://javarevisited.blogspot.com/2015/07/3-ways-to-read-file-line-by-line-in.html

【讨论】:

    【解决方案3】:

    因为您想解决这个问题并想了解流在这种情况下如何发挥作用

    1. 读取文件(使用 Java8),这将获取文件中的所有行:Streamlines = Files.lines(Paths.get(filePath))
    2. 逐行读取此文件:lines.map(line -> line.split(pattern)),通过拆分行,您将从行中获得三个部分
    3. 将获得的参数传递给函数n : forEach(arg -> createGraphe(arg[0], arg[1], arg[2]);

    如果你想实现这一点,我希望这对你的回答来说是相当详尽的

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-17
      • 2016-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-10
      相关资源
      最近更新 更多