gpt4 book ai didi

java - 使用 Java 8 处理和拆分大文件

转载 作者:塔克拉玛干 更新时间:2023-11-01 23:08:39 27 4
gpt4 key购买 nike

我是 Java 8 的新手,我刚刚开始使用 NIO 包进行文件处理。我需要有关如何处理大文件的帮助——每个文件从 100,000 行到 1,000,000 行不等——通过将每一行转换为特定格式并将格式化的行写入新文件。生成的新文件每个文件最多只能包含 100,000 行。所以:

  • 如果我有一个 500,000 行的文件要处理,我必须转换那些行并将它们分发并打印在 5 个新文件上。
  • 如果我有一个 745,000 行的文件需要处理,我必须转换那些行并将它们打印在 8 个新文件上。

我很难找到一种可以有效利用 Java 8 新特性的方法。我已经开始根据大文件的行数确定要生成的新文件的数量,然后创建那些新的空文件:

Path largFile = Path.get("path\to\file");
long recordCount = Files.lines(file).count();
int maxRecordOfNewFiles = 100000;
int numberOfNewFiles = 1;
if (recordCount > maxRecordOfNewFiles) {
numberOfNewFiles = Math.toIntExact(recordCount / maxRecordOfNewFiles);
if (Math.toIntExact(recordCount % maxRecordOfNewFiles) > 0) {
numberOfNewFiles ++;
}
}

IntStream.rangeClosed(1, numberOfNewFiles).forEach((i)
-> {
try {
Path newFile = Paths.get("path\to\newFiles\newFile1.txt");
Files.createFile(cdpFile);
} catch (IOException iOex) {
}
});

但是当我通过 Files.lines(largeFile).forEach(()) 功能遍历 largeFile 的行时,我迷失了如何继续格式化前 100,000 行,然后确定第一个新文件并将它们打印在该文件上,然后将第二批 100,000 行打印到第二个新文件,依此类推。

任何帮助将不胜感激。 :)

最佳答案

当您开始构思批处理时,我认为您应该考虑使用专门用于批处理的框架。您可能想要处理重启、调度... Spring Batch非常好,已经提供了你想要的:MultiResourceItemWriter以每个文件的最大行数和 FlatFileItemReader 写入多个文件从文件中读取数据。


在这种情况下,您想要的是遍历输入文件的每一行,并在多个输出文件中写入每一行的转换。

一种方法是在输入文件的行上创建一个 Stream,映射每一行并将其发送到自定义编写器。此自定义编写器将在达到每个文件的最大行数时执行切换编写器的逻辑。

在下面的代码中,MyWriter 打开一个文件的 BufferedWriter。当达到 maxLines(它的倍数)时,关闭此写入器并打开另一个写入器,从而增加 currentFile。这样,我们正在写入多个文件对读者来说是透明的。

public static void main(String[] args) throws IOException {
try (
MyWriter writer = new MyWriter(10);
Stream<String> lines = Files.lines(Paths.get("path/to/file"));
) {
lines.map(l -> /* do transformation here */ l).forEach(writer::write);
}
}

private static class MyWriter implements AutoCloseable {

private long count = 0, currentFile = 1, maxLines = 0;
private BufferedWriter bw = null;

public MyWriter(long maxLines) {
this.maxLines = maxLines;
}

public void write(String line) {
try {
if (count % maxLines == 0) {
close();
bw = Files.newBufferedWriter(Paths.get("path/to/newFiles/newFile" + currentFile++ + ".txt"));
}
bw.write(line);
bw.newLine();
count++;
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}

@Override
public void close() throws IOException {
if (bw != null) bw.close();
}
}

关于java - 使用 Java 8 处理和拆分大文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34940498/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com