将Java StringBuilder转储到文件

Pat*_*ick 35 java stringbuilder file

将StringBuilder转储到文本文件的最有效/最优雅的方法是什么?

你可以做:

outputStream.write(stringBuilder.toString().getBytes());
Run Code Online (Sandbox Code Playgroud)

但这对于一个很长的文件有效吗?

有没有更好的办法?

Kev*_*ion 40

正如其他人所指出的,使用Writer,并使用BufferedWriter,但不要writer.write(stringBuilder.toString());只调用writer.append(stringBuilder);.

编辑:但是,我看到你接受了一个不同的答案,因为它是一个单行.但该解决方案有两个问题:

  1. 它不接受java.nio.Charset.坏.您应该始终明确指定Charset.

  2. 它仍然让你受苦stringBuilder.toString().如果简单就是您所追求的,请从Guava项目中尝试以下内容:

Files.write(stringBuilder,file,Charsets.UTF_8)

  • 查看Writer.append()的源代码,我们看到一个调用write(csq.toString(),所以它仍然在字符串构建器对象上调用toString().所以没有获得. (8认同)
  • 另外,感谢澄清FileUtils,但仍然将Charset指定为String是蹩脚的. (3认同)

rob*_*rob 24

您应该使用BufferedWriter来优化写入(始终使用Writer而不是OutputStream写入字符数据).如果您没有编写字符数据,则可以使用BufferedOutputStream.

File file = new File("path/to/file.txt");
BufferedWriter writer = null;
try {
    writer = new BufferedWriter(new FileWriter(file));
    writer.write(stringBuilder.toString());
} finally {
    if (writer != null) writer.close();
}
Run Code Online (Sandbox Code Playgroud)

或者,使用try-with-resources(Java 7及更高版本)

File file = new File("path/to/file.txt");
try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) {
    writer.write(stringBuilder.toString());
}
Run Code Online (Sandbox Code Playgroud)

由于您最终要写入文件,更好的方法是更频繁地写入BufferedWriter,而不是在内存中创建一个巨大的StringBuilder并在最后编写所有内容(根据您的用例,您甚至可以完全消除StringBuilder).在处理过程中逐步写入将节省内存并更好地利用有限的I/O带宽,除非另一个线程在您编写的同时尝试从磁盘读取大量数据.


Naw*_*Man 15

好吧,如果字符串很大,toString().getBytes()将创建重复的字节(2或3次).字符串的大小.

为避免这种情况,您可以提取字符串的块并将其写入单独的部分.

以下是它的外观:

final StringBuilder aSB = ...;
final int    aLength = aSB.length();
final int    aChunk  = 1024;
final char[] aChars  = new char[aChunk];

for(int aPosStart = 0; aPosStart < aLength; aPosStart += aChunk) {
    final int aPosEnd = Math.min(aPosStart + aChunk, aLength);
    aSB.getChars(aPosStart, aPosEnd, aChars, 0);                 // Create no new buffer
    final CharArrayReader aCARead = new CharArrayReader(aChars); // Create no new buffer

    // This may be slow but it will not create any more buffer (for bytes)
    int aByte;
    while((aByte = aCARead.read()) != -1)
        outputStream.write(aByte);
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助.

  • +1是最节省内存的解决方案. (4认同)
  • +1这不是真的慢,只是用50MB字符串测试它.但它确实可以节省内存.(约2MB,其他方法为130MB) (3认同)

Mik*_*ler 14

您可以使用Apache Commons IO库,它为您提供FileUtils:

FileUtils.writeStringToFile(file, stringBuilder.toString(), Charset.forName("UTF-8"))
Run Code Online (Sandbox Code Playgroud)