如何在文件中提取唯一的行> 10 GB,4GB RAM

时间:2015-11-04 12:10:32

标签: java unique bigdata

我有一台装有4 GB RAM的PC和一个内存使用量为10 GB的文件。现在我想检查一下,如果文件中的每一行都是唯一的,那么我写了下面的代码:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

public class Cleaner {

    public static void main(String[] args) throws IOException {
        if (args.length < 2) {
            System.out.println("Too less parameters!");
            return;
        }

        File file = new File(args[0]);
        BufferedReader buff = new BufferedReader(new FileReader(file));
        String line;
        Set<String> set = new HashSet<String>();
        while ((line = buff.readLine()) != null) {
            set.add(line);
        }
        FileWriter fw = new FileWriter(args[1]);
        for (String s : set) {
            fw.write(s + "\n");
            fw.flush();
        }
        fw.close();
        buff.close();

    }

}

但是我得到一个OutOfMemoryException所以我的问题是:
如何更改代码以获取每行唯一的文件?
感谢您的帮助。

3 个答案:

答案 0 :(得分:0)

由于你的RAM内存,你无法以这种方式进行操作。相反,您可以读取文件并生成具有固定大小(f.e:10.000行)的n个文件读取一行并将其放入实际文件中。当您达到文件限制时,打开一个新文件,释放所有对象以进行内存保存,然后再进行第二次循环,并使用字符串(对于该行)与n个生成的文件比较原始文件的每一行。也许通过这种方式你可以避免记忆差距。

有点奇怪,并且会是一个缓慢的过程,但这样我觉得你可以达到你的要求。

如果您需要密码,请与我们联系。

希望帮助

答案 1 :(得分:0)

您可以尝试首先查找重复的线条哈希以识别可能的重复线条:

Map<Integer, Integer> hashes = new HashMap<> ();
Map<Integer, Integer> dupes = new HashMap<> ();
int i = 0;
while ((line = buff.readLine()) != null) {
  int hash = line.hashCode();
  Integer previous = hashes.get(hash);
  if (previous != null) { //potential duplicate
    dupes.put(i, previous);
  } else {
    hashes.put(hash, i);
  }
  ++i;
}

最后,您有可能重复的列表。如果dupes为空,则没有重复,如果不是,则可以对文件进行第二次传递以检查这些行是否真的相同。

答案 2 :(得分:-1)

你可以用这样的东西作弊:(例如Groovy,但等效的Java可以工作)

def hashes = []
def writer = new PrintWriter(new FileWriter("out.txt"))
new File('test.txt').eachLine { line ->
    def hashCode = DigestUtils.sha256Hex(line) //Commons digest library
    if (!(hashCode in hashes)) {
        hashes << hashCode
        writer.println(line)
    }
}
writer.close()

这不应该需要超过大约1GB的RAM来运行。与标准hashCode方法相比,SHA256哈希可以比线条的唯一性更加确定。