读取和处理25GB的大文本文件

时间:2012-01-11 04:03:05

标签: java file file-io large-files

我必须阅读25 GB的大文本文件,并且需要在15-20分钟内处理此文件。此文件将具有多个页眉和页脚部分。

我尝试使用CSplit根据标题拆分此文件,但是需要大约24到25分钟将其拆分为基于标头的多个文件,这根本不可接受。

我使用BufferReaderBufferWiter以及FileReaderFileWriter尝试了顺序阅读和写作。这需要超过27分钟。再说一次,这是不可接受的。

我尝试了另一种方法,例如获取每个标头的起始索引,然后使用RandomAccessFile运行多个线程以从特定位置读取文件。但是没有运气。

我如何达到我的要求?

  

可能重复:

     

Read large files in Java

4 个答案:

答案 0 :(得分:8)

尝试使用较大的缓冲区读取大小(例如,20MB而不是2MB)来更快地处理数据。由于速度慢和字符转换,也不要使用BufferedReader。

之前已经问过这个问题:Read large files in Java

答案 1 :(得分:6)

您需要确保IO足够快,而无需进行处理,因为我怀疑处理,而不是IO会降低您的速度。您应该可以从硬盘驱动器获得80 MB / s的速度,从SSD驱动器获得最高400 MB / s的速度。这意味着您可以在一秒钟内阅读整个内容。

尝试以下内容,这不是最快的,但最简单的。

long start = System.nanoTime();
byte[] bytes = new byte[32*1024];
FileInputStream fis = new FileInputStream(fileName);
int len;
while((len = fis.read(bytes)) > 0);
long time = System.nanoTime() - start;
System.out.printf("Took %.3f seconds%n", time/1e9);

除非您发现至少达到50 MB / s,否则会出现硬件问题。

答案 2 :(得分:1)

尝试使用java.nio更好地利用操作系统功能。避免复制数据(例如,复制到字符串中),但尝试使用偏移。我相信java.nio类甚至可以使用方法将数据从一个缓冲区传输到另一个缓冲区而根本不将数据拉入java层(至少在linux上),但这实际上会转化为操作系统调用。

对于许多现代Web服务器而言,这种技术对于它们可以提供静态数据的性能至关重要:基本上它们尽可能多地委托给操作系统,以避免将其复制到主存储器中。

让我强调一下:只需通过一个25 GB的字节缓冲区来寻找比将其转换为Java字符串(可能需要字符串编码/解码 - 和复制)快得多。任何可以节省你的副本和内存管理的东西都会有所帮助。

答案 3 :(得分:1)

如果平台是正确的,你可能想要炮轰并调用cat和sed的组合。如果不是,您可能仍希望通过命令行shell并使用perl。对于绝对必须是Java进行实际处理的情况,其他人已经提供了足够的答案。

但要保持警惕,炮轰并非没有问题。但是perl或sed可能是唯一可用于在您的时间范围内抓取并更改25GB文本的广泛工具。