Dumping a Java StringBuilder to File

前端 未结 9 603
南旧
南旧 2021-02-01 14:17

What is the most efficient/elegant way to dump a StringBuilder to a text file?

You can do:

outputStream.write(stringBuilder.toString().getBytes());


        
相关标签:
9条回答
  • 2021-02-01 14:22

    Benchmarks for most answers here + improved implementation: https://www.genuitec.com/dump-a-stringbuilder-to-file/

    The final implementation is along the lines of

    try {
        BufferedWriter bw = new BufferedWriter(
                new OutputStreamWriter(
                        new FileOutputStream(file, append), charset), BUFFER_SIZE);
        try {
            final int length = sb.length();
            final char[] chars = new char[BUFFER_SIZE];
            int idxEnd;
            for ( int idxStart=0; idxStart<length; idxStart=idxEnd ) {
                idxEnd = Math.min(idxStart + BUFFER_SIZE, length);
                sb.getChars(idxStart, idxEnd, chars, 0);
                bw.write(chars, 0, idxEnd - idxStart);
            }
            bw.flush();
        } finally {
            bw.close();
        }
    } catch ( IOException ex ) {
        ex.printStackTrace();
    }
    
    0 讨论(0)
  • 2021-02-01 14:26

    You could use the Apache Commons IO library, which gives you FileUtils:

    FileUtils.writeStringToFile(file, stringBuilder.toString(), Charset.forName("UTF-8"))
    
    0 讨论(0)
  • 2021-02-01 14:29

    As pointed out by others, use a Writer, and use a BufferedWriter, but then don't call writer.write(stringBuilder.toString()); instead just writer.append(stringBuilder);.

    EDIT: But, I see that you accepted a different answer because it was a one-liner. But that solution has two problems:

    1. it doesn't accept a java.nio.Charset. BAD. You should always specify a Charset explicitly.

    2. it's still making you suffer a stringBuilder.toString(). If the simplicity is really what you're after, try the following from the Guava project:

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

    0 讨论(0)
  • 2021-02-01 14:32

    You should use a BufferedWriter to optimize the writes (always write character data using a Writer instead of an OutputStream). If you weren't writing character data, you would use a 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();
    }
    

    or, using try-with-resources (Java 7 and up)

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

    Since you're ultimately writing to a file, a better approach would be to write to the BufferedWriter more often instead of creating a huge StringBuilder in-memory and writing everything at the end (depending on your use-case, you might even be able to eliminate the StringBuilder entirely). Writing incrementally during processing will save memory and will make better use of your limited I/O bandwidth, unless another thread is trying to read a lot of data from the disk at the same time you're writing.

    0 讨论(0)
  • 2021-02-01 14:35

    Since java 8 you only need to do this:

    Files.write(Paths.get("/path/to/file/file_name.extension"), stringBuilder.toString().getBytes());

    You don't need any third party libraries to do that.

    0 讨论(0)
  • 2021-02-01 14:36

    Well, if the string is huge, toString().getBytes() will create duplicate bytes (2 or 3 times). The size of the string.

    To avoid this, you can extract chunk of the string and write it in separate parts.

    Here is how it may looks:

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

    Hope this helps.

    0 讨论(0)
提交回复
热议问题