如何有效地拆分文本文件?

时间:2013-09-25 09:51:51

标签: java

我有一个txt文件,它的大小大于1GB,每行都有一条记录。现在我想根据record.hashcode()%100将此文件拆分为100个txt文件,我该如何高效地完成?

每条记录都有不同的长度,这里的效率是时间和记忆

2 个答案:

答案 0 :(得分:2)

尝试使用BufferedReader同时读写。据我所知,它适用于大文件。

主要的想法是读取行并立即将其写入其他文件。只有当你排长队时,你才能获得糟糕的表现。

不要将它用于二进制文件!

int maxlinesNumber = 1000; // I took it randomly, 
BufferedReader rd = null;
BufferedWriter wt = null;

try {
  rd = new BufferedReader(
              new InputStreamReader(
                  new FileInputStream("/yourfile.txt"), "UTF-8")
              );

 int count = 0;

for (String line; (line = reader.readLine()) != null;) {
    if (count++ % maxlinesNumber == 0) {
        close(wt);
        wt = new BufferedWriter(
                   new OutputStreamWriter(
                      new FileOutputStream(
             "/newSmalfile" + (count / maxlinesNumber) + ".txt"), "UTF-8")
              );
    }
    wt.write(line);
    wt.newLine();
 }
} finally {
close(wt);
close(rd);
}

关于文件的确切数量,我认为你在这里失去了计算小文件大小的效率。

您可以尝试使用相同的方式,但读取字节而不是行。但这是方向。

答案 1 :(得分:0)

我以前做过这种事。它们对性能至关重要(对我而言,正如我通过网络写入SAN)以并行处理写入。即使你的阅读是连续的,也可能不是太糟糕。

基本算法:

  1. 使用有限数量的线程创建一个ExecutorService。
  2. 创建一个包含所有输出文件的地图
  3. 打开输出文件,创建一个Writer并使用1..100
  4. 中的键将它们添加到地图中
  5. 从循环中的输入中读取每一行,并将其作为任务添加到Executor
  6. 在任务中,它在与读者分开的线程中运行,解析行,计算哈希值,查找文件,同步文件,以便其他线程不会踩你,然后写行
  7. 关闭所有文件
  8. 中提琴

    陷阱:

    1. 当执行程序服务的输入队列变满时,会发生不好的事情,具体取决于它的配置方式。此外,无限制的队列也不好。
    2. 文件对象的同步看起来不太好,但我曾经尝试过另一种方法,确保每个文件都有一个线程,因此不需要锁定,但它并不比ExecutorService方法快,所以在最后它不值得努力。