在Java中同时迭代两个非常大的文件

时间:2011-10-01 02:54:04

标签: java memory-management large-files

我需要合并两个非常大的文件(每个大约1G),将第一行写入输出文件中的4行,而不是从第二行写入4。等等到最后。两个文件都有相同的行数,这个数字可以被4整除。在Java中最有效的方法是什么?

3 个答案:

答案 0 :(得分:0)

我喜欢使用Decorator模式。创建两个类,每个类代表一个BufferedReader实例。

例如,

class First
{
   BufferedReader br;
   ...
   public String getLine()
    {
       return br.readLine();
     }
}

class Second
{
  BufferedReader br;
  ...
  public String [] getLines()
   {
     //read four lines and return it
   }
}

答案 1 :(得分:0)

试一下,看看需要多长时间。相应地调整n。如果它太慢,请尝试使用nio。

import java.io.*;
class Time {
    Time() {}
    long dt() {
        return System.currentTimeMillis() - t0;
    }
    final long t0 = System.currentTimeMillis();
}
public class Main {
    public static void create(File file1, File file2, int n) throws Exception {
        BufferedWriter bw1 = new BufferedWriter(new FileWriter(file1));
        write(bw1, n, "foo");
        bw1.close();
        BufferedWriter bw2 = new BufferedWriter(new FileWriter(file2));
        write(bw2, n, "bar");
        bw2.close();
    }
    private static void write(BufferedWriter bw, int n, String line) throws IOException {
        for (int i = 0; i < n; i++) {
            bw.write(line);
            bw.write(lineSeparator);
        }
    }
    private static void write4(BufferedReader br1, BufferedWriter bw, String line) throws IOException {
        bw.write(line);
        bw.write(lineSeparator);
        for (int i = 0; i < 3; i++) {
            line = br1.readLine();
            bw.write(line);
            bw.write(lineSeparator);
        }
    }
    public static void main(String[] args) throws Exception {
        File file1 = new File("file1");
        File file2 = new File("file2");
        if (!file1.exists()) {
            create(file1, file2, 10000000);
        }
        File file3 = new File("file3");
        Time time=new Time();
        BufferedReader br1 = new BufferedReader(new FileReader(file1));
        BufferedReader br2 = new BufferedReader(new FileReader(file2));
        BufferedWriter bw = new BufferedWriter(new FileWriter(file3));
        String line1, line2;
        while ((line1 = br1.readLine()) != null) {
            write4(br1, bw, line1);
            line2 = br2.readLine();
            write4(br2, bw, line2);
        }
        br1.close();
        br2.close();
        bw.close();
        System.out.println(time.dt()/1000.+" s.");
    }
    static final String lineSeparator = System.getProperty("line.separator");
}

答案 2 :(得分:0)

很抱歉,如果已经提出了这个想法:)

我认为最快的方法是创建3个线程。 t1&amp; t2将从两个输入文件中读取,每个线程将拥有自己的队列(这是线程安全的),线程将读取4行并将它们放入其队列中。 t3将是写入线程,它将交替读取两个队列中的节点并将它们放入新的合并文件中。我认为这是一个很好的解决方案,因为它允许并行i \ o到所有三个文件(并且这里是瓶颈......)和线程之间的最小交互。