如何逐行复制大数据文件?

mem*_*und 9 java java-io java-stream

我有一个35GB的CSV文件。我想读取每一行,并在符合条件的情况下将其写到新的CSV中。

try (BufferedWriter writer = Files.newBufferedWriter(Paths.get("source.csv"))) {
    try (BufferedReader br = Files.newBufferedReader(Paths.get("target.csv"))) {
        br.lines().parallel()
            .filter(line -> StringUtils.isNotBlank(line)) //bit more complex in real world
            .forEach(line -> {
                writer.write(line + "\n");
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

这大约需要。7分钟 是否可以进一步加快该过程?

Joo*_*gen 3

如果可以的话,您可以使用 GZipInputStream/GZipOutputStream 来最小化磁盘 I/O。

Files.newBufferedReader/Writer 使用默认缓冲区大小,我相信是 8 KB。您可以尝试更大的缓冲区。

转换为字符串、Unicode 会减慢速度(并使用两倍的内存)。使用的UTF-8并不像StandardCharsets.ISO_8859_1那么简单。

最好的情况是,您可以在大部分情况下使用字节,并且仅针对特定的 CSV 字段将它们转换为字符串。

内存映射文件可能是最合适的。文件范围可能会使用并行性,从而吐出文件。

try (FileChannel sourceChannel = new RandomAccessFile("source.csv","r").getChannel(); ...
MappedByteBuffer buf = sourceChannel.map(...);
Run Code Online (Sandbox Code Playgroud)

这将变得有点多的代码,使行正确(byte)'\n',但不会过于复杂。