所以我有一个非常大的数字(1500万位)存储在一个文本文件中,我正在使用这种方法来读取数字
BufferedReader Br1 = null;
StringBuilder Final = new StringBuilder("");
System.out.println("Loading......");
Br1 = new BufferedReader (new FileReader("NumberFind.txt"));
String Line = Br1.readLine();
while(Line != null) {
Final.append(Line);
Line = Br1.readLine();
}
sum1 = new BigInteger(Final.toString());
Br1.close();
System.out.println("Loaded");
这可行,但加载整数需要大约45分钟,是否有更快的加载方式?
答案 0 :(得分:0)
如果你的文件只有一个数字,你的文件只有14.3兆字节。我不知道BufferedReader,BigInteger等的怪癖会导致45分钟的加载,但它可能就是那个行读取循环。您应该能够在几秒钟内将整个文件读入内存,而不是几分钟。
尝试将整个文件(或可能只是包含该编号的部分)读入没有BufferedReader的字符串中。请参阅FileReader.readAsBinaryString()以实现该目的。
将内存中的数字作为字符串后,您应该能够通过将字符串参数传递给它来构造一个新的BigInteger,就像您在上面的代码示例中所做的一样。
如果这不能解决所有问题,并且您需要更多见解,我建议缩小45分钟延迟发生的时间。我猜它是在你的阅读循环中,但我可能是错的。如果您在某些环境中,例如嵌入式设备,对CPU,磁盘读取时间等有不寻常的限制,可能是一个因素。
答案 1 :(得分:0)
可以创建具有文件大小初始容量的StringBuilder(可能减去行结尾)。
可以使用BigInteger而不是StringBuilder来节省大量内存来累积结果。这确实是否更快我不知道。
Path path = Paths.get("NumberFind.txt");
BigInteger n = Files.lines(path)
.reduce(// 1. the start value
BigDecimal.ZERO,
// 2. the accumulator adding the next line
(num, line) ->
num.scaleByPowerOfTen(line.length()).add(new BigDecimal(line)),
// 3. The combiner for a parallel stream (irrelevant)
(num1, num2) ->
num1.scaleByPowerOfTen(num2.toString().length()).add(num2))
.toBigInteger();
读取一行,将其转换为BigDecimal。先前的行累积到一个BigDecimal,然后必须乘以10 n ,其中n是行长度。
我使用BigDecimal,因为它有一个很好的scaleByPowerOfTen
。最后,BigDecimal被转换为BigInteger。
此解决方案可能会更慢。我很好奇。