从文本文件中读取巨大的字符串

时间:2012-11-26 17:12:23

标签: java string memory-leaks io

我有一个大文本文件,但没有任何换行符。它只包含一个长字符串(1个字符串的大字符串,包含所有ASCII字符),但到目前为止,任何工作都可以正常,因为我可以用Java读取整行到内存中,但我想知道是否有内存泄漏问题,因为文件变得像5GB +那么大,并且程序无法立即将整个文件读入内存,所以在这种情况下读取此类文件的最佳方法是什么?我们可以将这条巨大的线分成两部分甚至多块吗?

以下是我阅读文件的方式

   BufferedReader buf = new BufferedReader(new FileReader("input.txt"));
   String line;
   while((line = buf.readLine()) != null){

   }

6 个答案:

答案 0 :(得分:9)

单个字符串长度只有20亿个字符,每个字符使用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。

答案 1 :(得分:3)

不会有任何内存泄漏,因为JVM有自己的垃圾收集器。但是,您可能会耗尽堆空间。

在这种情况下,最好以可管理的方式导入和处理流。读入64MB左右并重复。

您还可能会发现将-Xmx参数添加到java调用中非常有用,以便增加JVM中可用的最大堆空间。

答案 2 :(得分:1)

最好以块的形式读取文件然后连接块或者做任何你想做的事情,因为如果它是一个大文件你正在阅读你会得到堆空间问题

一种简单的方法,如下所示

  InputStream is;
  OutputStream os;

  byte buffer[] = new byte[1024];
  int read;
  while((read = is.read(buffer)) != -1)
  {
      // do whatever you need with the buffer
  }

答案 3 :(得分:0)

除了读取块的想法之外,您还可以使用java.nio.MappedByteBuffer查看文件的内存映射区域。您仍将被限制为最大缓冲区大小Integer.MAX_VALUE。如果您要在一个块中进行分散访问,这可能比明确读取块更好。

答案 4 :(得分:0)

要从文件中读取块或将其写入某个文件,可以使用:

{
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);
}

答案 5 :(得分:-1)

您不会遇到任何内存泄漏问题,但可能会出现堆空间问题。要避免堆问题,请使用缓冲区。

这完全取决于您目前如何阅读该行。通过使用缓冲区可以避免所有堆问题。

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 
     }
}
相关问题