我有一台装有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所以我的问题是:
如何更改代码以获取每行唯一的文件?
感谢您的帮助。
答案 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哈希可以比线条的唯一性更加确定。