Java 从文本文件中读取一大行字符串

Java 从文本文件中读取一大行字符串,java,string,memory-leaks,io,Java,String,Memory Leaks,Io,我有一个大的文本文件,但没有任何换行符。它只包含一个长字符串(一个包含所有ASCII字符的大字符串行),但到目前为止,任何东西都可以正常工作,因为我可以用Java将整行内容读入内存,但我想知道是否会出现内存泄漏问题,因为文件变得像5GB+那样大,程序无法立即将整个文件读入内存,那么,在这种情况下,读取此类文件的最佳方式是什么?我们能把这条大线分成两部分甚至多个部分吗 下面是我如何读取文件的 BufferedReader buf = new BufferedReader(new FileRe

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

下面是我如何读取文件的

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

   }

不会有任何内存泄漏,因为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
  }

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

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

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 
     }
}
public void readLongString(字符串superlongString,int-size,BufferedReader-in){
char[]buffer=新字符[大小];

对于(int i=0;i,单个字符串的长度只能为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。

除了分块读取之外,您还可以使用java.nio.MappedByteBuffer查看文件的内存映射区域。您仍然将最大缓冲区大小限制为Integer.MAX_值。如果您使用ng块内的分散访问。

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

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

你现在用什么java方法来读这行?你能发布一些代码吗?它的2的功率往往表现更好,512到65536字节之间的大小往往很好,而8192是中间的(几何上)。你能解释一下吗?比如为什么2的幂往往表现得更好,为什么在512和65536之间?计算机内存的大小通常是2的幂,因为计算机使用二进制数。磁盘块总是2的幂。内存页大小是2的幂,例如4096。缓存大小通常是2的幂的倍数,例如32768或3*1024*1024。这意味着缓存大小(通常为64字节)、页面大小、磁盘块更有可能以二次方排列(不一定如此,但通常并不重要)使用两个大小的幂次函数有一点好处。随着块大小的增加,系统调用的开销会减少,但是非常大的块往往会受到缓存溢出的影响,例如,主缓存通常是32 KB。在基准测试中,围绕这些大小进行传输可以提供最佳性能。我想知道堆空间不足不是问题T是否被认为是内存泄漏?什么是内存泄漏?StAcExpRoad?内存泄漏是由于程序员错误造成的。当程序不再使用的内存页不会被用于垃圾收集时。在长时间运行的过程中,这意味着进程会随着时间的推移使用越来越多的内存。这是内存泄漏。装载这么多的东西,堆空间就用光了,这是不可能的。