读取巨大的文本文件 Java

3
我有一个包含10亿个π的数字的.txt文件。我将其作为字符串读入,但是会出现OutOfMemoryError错误。当我只有100万个数字时,它可以正常工作。我将字符串保存为char[]数组。 是否可能在循环遍历整个数组时以某种方式流式传输.txt文件?我只需要一种方法来将所有10亿个数字作为数组访问。

3
你需要对读取的数据进行哪种处理? - Arnaud
我正在循环遍历整个字符数组以查找某个数字...只需通过数组进行for循环。就这样。 - Steakie
“寻找某个数字”是什么意思?这个数字是π。你是指“寻找特定的数字序列”吗?如果是,需要多少位数字? - Klitos Kyriacou
是的,一串数字。大约4-9位左右。我需要一种方法将这10亿个数字作为数组访问。 - Steakie
为什么需要“以数组的方式访问所有10亿位数字”的方法?如果您有一个字符串,您可以像数组一样迭代char - Holger
4个回答

4
自Java 1以来,就有BufferedInputStream或者FileReader可供选择。
public int read(char cbuf[], int offset, int length) throws IOException 

我建议你从那里开始


这可能是我的问题的解决方案。但实施起来遇到了问题... 我会继续尝试的。 - Steakie
这里 BufferedInputStream 的相关性在哪里? - Holger
你说得对,我应该提到FileInputStream,它本身就有缓冲区,所以不需要BufferedInputStream。这里可能会有用:https://dev59.com/o2435IYBdhLWcg3w4UWs - Pavel Niedoba

0

这不仅是可能的,而且强烈建议并已经实践。通常做法是重用与Java库相同类型的接口(如InputStream等)。

在这种情况下,这可能意味着一个新的IntegerInputStream类,它将数字作为流输出。该类本身可以转发对FileInputStream的调用。在内部,您可以使用char[]数组来存储缓冲区并提高性能,或者像Pavel建议的那样通过BufferedInputStream进行调用,但最好将消费者与内部缓冲区管理隔离,并保持适当的抽象级别以符合使用案例(如圆周率的小数点)。


0
你可以使用 FileInputStream 打开文件,逐个字节地读取它们的 byte[],以避免 OOMError。

0
根据文档,
你应该能够获得一个长度为Integer.MAX_VALUE的字符串(根据Java规范始终为2147483647(231-1),这是数组的最大大小,String类用于内部存储)或者你最大堆大小的一半(因为每个字符占两个字节),以较小者为准。
这就是为什么会出现异常,
如果你不需要整个10亿个字符,可以尝试使用缓冲区,它不会将整个内容加载到内存中。
BufferedReader br = new BufferedReader(new FileReader(new File("path to file")));
char[] data=new char[1000000] ;//however many chars you want;
int i=0;
while ((c = br.read()) != -1 && i<data.length) {
    data[i++]= c;
}

br.close();

你为什么要读取多达1000000个单个字符,而不是直接在读取器上调用read(char[])呢?这样,你就不需要使用BufferedReader来解决过多的read()调用问题了... - Holger
@Holger 我猜那是另一种做法。就复杂度而言,两种解决方案应该差不多。但是,我同意一行代码的解决方案更好。 - nafas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接