Java 使用圆周率的 10 亿位

Java use 1 billion digits of pi

我正在尝试编写一个程序来搜索 pi 的前 10 亿位数字并找到用户指定的数字,我面临的问题是如何使用 pi...我有一个 .txt 文件包含 pi(我也将它分解为 96 个不同的文件,因为 java 无法处理这么大的文件)所有数字都在第一行.... 代码(仅使用96个文件读取和保存pi):

for(int i = 1;i <= 96; i++){
        String filename = "";
        if(i <= 9){
            filename = "res//t//output2_00000" + i + "(500001).txt";
        }else{
            filename = "res//t//output2_0000" + i + "(500001).txt";
        }
        Scanner inFile = new Scanner(new FileReader(filename));
        ar.add(inFile.nextLine());
    }
    List<String> pi = new ArrayList<String>();
    for(int i = 0; i<97;i++){
        System.out.println(i);
        for(String j : ar.get(i).split("")){
            pi.add(j);
        }
    }

这似乎工作正常,直到崩溃并出现以下错误(最后的打印语句是 3):

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.lang.String.substring(Unknown Source)
at java.lang.String.subSequence(Unknown Source)
at java.util.regex.Pattern.split(Unknown Source)
at java.lang.String.split(Unknown Source)
at java.lang.String.split(Unknown Source)
at main.Main.main(Main.java:29)

有没有办法克服它,有没有办法让它运行得更快? 提前致谢。

如果您尝试将超过 1GB 的数据加载到堆中,您可能会用完堆内存。只需检查每个文件的搜索字符串,然后关闭文件。

不要拆分文本文件:这是错误的解决方案,找到一个跨文件拆分的数字会很痛苦。 当然 Java 可以处理大文件:您认为用 Java 编写的数据库还能如何工作?!

考虑使用 Apache Commons IO,它为您提供 LineIterator:

LineIterator it = FileUtils.lineIterator(theFile, "UTF-8"/*probably*/);
try {
    while (it.hasNext()) {
        String line = it.nextLine();
        // do something with line
    }
} finally {
    LineIterator.closeQuietly(it);
}

您不需要将整个文件加载到内存中。使用 RandomAccessFile,您可以打开一个文件,将光标放在您想要的位置并从中读取:

RandomAccessFile raf = new RandomAccessFile(
  new File("/home/adenoyelle/dev/pi.txt"), "r");
raf.seek(1_000_000);
System.out.println(raf.read());

注意:raf.read() returns一个字节的数据。您可能需要根据需要重新解释它。

示例:

for(int i = 0; i< 10; i++) {
  raf.seek(i);
  System.out.println((char)raf.read());
}

输出:

3
.
1
4
1
5
9
2
6
5

注意 2 :如 SaviourSelf 所述,如果您需要一次读取多个字节,请选择 read(byte [] b).