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

Fastest way to read a large number from text file

所以我在文本文件中存储了一个非常大的数字(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 分钟,有没有更快的加载方法?

如果其中只有一个数字,您的文件只有 14.3 兆字节。我不知道 BufferedReader、BigInteger 等的什么怪癖导致了 45 分钟的加载,但它可能只是那个行读取循环。您应该能够在几秒钟内将整个文件读入内存,而不是几分钟。

尝试在没有 BufferedReader 的情况下将整个文件(或可能只是包含数字的部分)读入字符串。请参阅 FileReader.readAsBinaryString() 以完成此操作。

将数字作为字符串存储在内存中后,您应该能够像在上面的代码示例中所做的那样,通过将字符串参数传递给它来构造一个新的 BigInteger。

如果这不能解决所有问题,并且您想要更多见解,我建议缩小发生 45 分钟延迟的范围。我猜它在你的线阅读循环中,但我可能是错的。如果您在某些环境中,例如嵌入式设备,对 CPU、磁盘读取时间等有异常限制,这可能是一个因素。

可以创建初始容量为文件大小(可能减去行尾)的 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,然后必须乘以 10n,其中 n 是行长度。

我使用 BigDecimal,因为它有一个很好的 scaleByPowerOfTen。最后,BigDecimal 被转换为 BigInteger。

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