-1

我有一个 txt 文件,它的大小大于 1GB,每一行都有一条记录。现在我想根据record.hashcode()%100把这个文件拆分成100个txt文件,怎样才能高效呢?

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

4

2 回答 2

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);
}

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

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

于 2013-09-25T09:58:04.860 回答
0

我以前做过这种事情。它们对性能的关键是(对我来说很好,因为我正在通过网络写入 SAN)以并行写入。即使您的阅读是顺序的,也可能不会太糟糕。

基本算法:

  1. 创建一个 ExecutorService,具有有限数量的线程。
  2. 创建一个地图来保存所有的输出文件
  3. 打开输出文件,创建一个 Writer 并将它们添加到地图中,键为 1..100
  4. 循环读取输入中的每一行,并将其作为任务添加到 Executor
  5. 在任务中,它在与阅读器不同的线程中运行,解析行,计算哈希,查找文件,在文件上同步,这样其他线程就不会踩到你,然后写行
  6. 关闭所有文件

中提琴

陷阱:

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