我正在尝试制作一个程序,它将搜索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)
有没有办法克服这个问题,有没有办法让它变得更快? 提前谢谢。
答案 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);
}