将文本文件读取到字符串而不占用大量内存

时间:2013-08-25 11:48:21

标签: java file-io memory-leaks nio

我尝试使用NIO(读取单个文件的速度最慢),BufferedInputStream以及逐行读取文件(每次传递平均600毫秒)来测量将文件读入字符串的几种方法的性能,然后这个流使用Filereader和一个固定大小的数组作为缓冲区(最快)

文件是Windows .txt文件格式的95 MB纯文本。将字符转换为字符串确实是瓶颈,但我注意到的是这种方法的大量内存消耗。对于95 MB的lorem ipsum,这最多可消耗1 GB的RAM。我还没找到原因。

我试过没有效果:

通过调用System.gc()发出垃圾收集器 在方法结束之前将所有指针变量设置为null(但它们应该是无论如何,它们仅在方法中定义)。

private void testCharStream() {
            File f = f = new File("c:/Downloads/test.txt");
    long oldTime = System.currentTimeMillis();
    char[] cbuf = new char[8192];
    StringBuilder builder = new StringBuilder();
    try {

        FileReader reader = new FileReader(f);

        while (reader.read(cbuf) != -1) {
            builder.append(cbuf);
        }

        reader.close();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    long currentTime = System.currentTimeMillis();

    System.out.println(currentTime - oldTime);
}

4 个答案:

答案 0 :(得分:1)

尝试Apache Commons IO:http://commons.apache.org/proper/commons-io/ 我没有对它进行基准测试,但我认为代码已经过优化。

答案 1 :(得分:0)

我提出了不错的解决方案。使用Apache Commons IO Package,内存峰值 777,1 MB ,最低220 MB,平均需要710 ms,95 MB文本文件为红色。

我所做的是在方法结束时将指向StringBuilder对象的变量设置为null,并建议垃圾colletor实际执行它的工作(System.gc())。内存峰值 540 MB ,超过以前达到的值的1/2!此外,通过将缓冲区大小更改为1024意味着每次通过40毫秒,从490到450甚至更低。所以我的函数只需要 63.4%的Apache时间来读取文件。这几乎 40%。任何有关如何提高性能的想法都会进一步改善?

这是功能。

private void testCharStream() {
    long oldTime = System.currentTimeMillis();
    char[] cbuf = new char[1024];
    StringBuilder builder = new StringBuilder();

    try {

        FileReader reader = new FileReader(f);

        while (reader.read(cbuf) != -1) {
            builder.append(cbuf);
        }

        reader.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    long currentTime = System.currentTimeMillis();
    builder = null;
    System.gc();
    System.out.println(currentTime - oldTime);
}

答案 2 :(得分:0)

为了获得更好的性能,您可以使用BufferedReader。此类允许您逐行读取文件。这种方法可以更快地执行任务,而不是通过逐字阅读文件来浪费时间。您可以在半秒内读取纯文本文件(大小:1 MB)。只需使用以下代码即可。

  

文件f =新文件(“文件路径”);
  FileReader fr = new FileReader(f)
  BufferedReader br = new BufferedReader(fr);

  String line =“”;
  StringBuilder builder = new StringBuilder();
  试试{
  while((line = br.readLine())!= null)
  builder.append(线+ “\ n”);
  }
  捕获(例外e)
  {
e.printStackTrace();
}

您可以在使用System.currentTimeMillis()时查看阅读文件所需的时间。

答案 3 :(得分:0)

请查看下面的链接,阅读真正的Java大文件(150GB)。

[http://www.answerques.com/s1imeegPeQqU/reading-really-big-files-with-java][1]