Java使用10亿个pi

时间:2016-02-22 15:58:25

标签: java arrays list out-of-memory pi

我正在尝试制作一个程序,它将搜索pi的前10亿个数字并找到用户指定的数字,我面临的问题是如何使用pi ...我有一个包含pi的.txt文件(我也把它分成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)

有没有办法克服这个问题,有没有办法让它变得更快? 提前谢谢。

3 个答案:

答案 0 :(得分:3)

您无需在内存中加载整个文件。使用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()返回一个数据字节。您可能需要根据需要重新解释它。

示例:

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)

答案 1 :(得分:-1)

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

答案 2 :(得分:-1)

不要拆分文本文件:这是错误的解决方案,找到一个分散在文件中的数字将是一件痛苦的事。 当然 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);
}