从文本文件中读取大量数字的最快方法

时间:2017-05-16 17:42:12

标签: java file bufferedreader

所以我有一个非常大的数字(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分钟,是否有更快的加载方式?

2 个答案:

答案 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。

此解决方案可能会更慢。我很好奇。