我有一个大的文本文件,但没有任何换行符。 它只是包含一个长字符串(字符串的所有ASCII字符1条巨大的线),但迄今为止什么工作得很好,因为我可以能够读取整条生产线到Java的内存,但我想知道是否有可能是一个记忆泄漏的问题,因为文件变得非常大如5GB +和程序无法读取整个文件到内存中一次,所以在这种情况下会是怎样读这样的文件的最好方法? 我们可以打破巨大的线分为两个部分,甚至多块?
以下是我读文件
BufferedReader buf = new BufferedReader(new FileReader("input.txt"));
String line;
while((line = buf.readLine()) != null){
}
一个字符串只能是2十亿个字符长,将每个字符使用2个字节,所以如果你能读一个5 GB线将使用的内存10 GB。
我建议你阅读块中的文本。
Reader reader = new FileReader("input.txt");
try {
char[] chars = new char[8192];
for(int len; (len = reader.read(chars)) > 0;) {
// process chars.
}
} finally {
reader.close();
}
这将使用大约16 KB不管文件的大小。
不会有任何形式的内存泄漏 ,因为JVM有自己的垃圾收集器。 然而,你可能会耗尽堆空间。
在这样的情况下,它始终是最好的导入和处理在管理的部分流。 阅读64MB左右,并重复。
你也可能会发现它有用的添加-Xmx
参数,以你的java
号召,以增加JVM中可用的最大堆空间。
它能够更好地读取数据块的文件,然后将拼接块或做任何你想做机智它,因为如果它是你正在阅读你会得到堆空间问题,一个大文件
一个简单的方法来做到这一点像下面
InputStream is;
OutputStream os;
byte buffer[] = new byte[1024];
int read;
while((read = is.read(buffer)) != -1)
{
// do whatever you need with the buffer
}
除了在大块读书的想法,你也可以看看使用java.nio.MappedByteBuffer文件的内存映射区域。 你仍然会被限制为Integer.MAX_VALUE的最大缓冲区大小。 这可能比明确阅读块,如果你将作出散落一大块内访问更好。
若要从文件中读取数据块或写相同的一些文件,这可以用于:
{
in = new FileReader("input.txt");
out = new FileWriter("output.txt");
char[] buffer = new char[1024];
int l = 0;
while ( (l = in.read(buffer)) > 0 ) {
out.write(buffer, 0, l);
}
你不会遇到任何内存泄漏问题,但可能堆空间的问题。 为了避免堆问题,使用缓冲。
这一切都取决于你如何目前读线路。 它是可以通过使用缓冲器,以避免所有堆问题。
public void readLongString(String superlongString, int size, BufferedReader in){
char[] buffer = new char[size];
for(int i=0;i<superlongString.length;i+=size;){
in.read(buffer, i, size)
//do stuff
}
}