StringBuilder如何用于读取Java中的大型文本文件?

时间:2012-03-24 17:28:09

标签: java string io stringbuilder stringbuffer

Java中是否有任何机制可以在读取大文本文件时减少内存使用量?

我遇到的几乎所有程序都使用String来读取文本文件。但是Java为每个String文本保留了空间。这就是为什么我认为因为存储了所有String对象所以内存使用量增加了。 java.io的所有类都处理String。但是,如果我们不使用StringBuilder,那么我们如何减少内存使用?

毕竟减少内存使用量是StringBuilder的主要关注点[因为它不像String那样不可变]。那么我们如何在不使用String的情况下利用它在Java I / O操作中的功能,即不使用这样的东西:sb.append([String object]);

6 个答案:

答案 0 :(得分:1)

假设您有一个n个字符串,每个字符串都是您从输入中读取的 - 为简单起见。

在读取时对strigns使用operator+将在每次连接字符串时创建一个String对象,因此您将获得长度为1,2,3,...,n的字符串

因此,除了从输入中读取的1 + 2 + .. + n = O(n^2)字符串之外,组合字符串的总内存使用量为n

如果您使用StringBuilder创建最终字符串,则实际创建n - 输入[长度为1]和最终字符串的一个对象 - 大小为n ,总内存使用量为1 + 1 + .. + 1 + n = O(n)

因此,即使您使用sb.append(String) - 空间使用也是渐进式的,然后创建所有中间字符串 - 因为您不需要创建中间String对象。

此外 - 使用StringBuilder时性能[时间]应该更好 - 因为你创建的对象较少,而且由于内存使用量较少 - gc不需要像连接时那样努力工作字符串天真。

(*)请注意,很容易看出上述内容仍然适用于任何长度的字符串。

答案 1 :(得分:0)

你可以使用StringBuilders的append char方法,以避免创建中间字符串,看看这篇文章:https://stackoverflow.com/a/9849624/102483请记住,没有办法减少最终字符串的内存占用,以便它是小于您正在阅读的文件的大小。

答案 2 :(得分:0)

根据您的操作,您可以创建一个String和/或StringBuilder对象池,这些对象使用您需要的值加载,清除然后重用。您可以将池配置为增长到最大值,如果池中的对象未使用,则将它们设置为null,最终将由垃圾回收器回收它们。

答案 3 :(得分:0)

你可能想要考虑这样的事情:

  BufferedReader reader = 
    new BufferedReader(
      new InputStreamReader(
        new ByteArrayInputStream(data)));
  String line;

  while ((line = reader.readLine()) != null)
    ...

有关详细信息,请参阅以下链接:

BufferedReader for large ByteBuffer?

http://www.tutorialspoint.com/java/java_bytearrayinputstream.htm

答案 4 :(得分:0)

Reader及其子类基于char和char [],只有便捷方法使用String。由于StringBuilder.append()接受char [],因此如果仅使用围绕char []构建的方法,则可以避免创建不必要的String对象。

请注意,虽然这减少了临时创建的String对象的数量,但总体内存要求保持不变,gc将收集任何其他创建的String。

答案 5 :(得分:0)

尝试使用StringBuilder附加从中读取的数据,而不是String 一份文件。如果您使用String,最终可能会创建多个 内存中的字符串对象。