2

I'm working on a Java project where I need to write a large number of lines to a file. I know BufferedWriter can improve performance compared to writing character by character, but I am unsure about the best practices for flushing the buffer and ensuring all data is written correctly.

Here’s my current code:

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

public class FileWriteExample {
    public static void main(String[] args) {
        try (BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt"))) {
            for (int i = 0; i < 100000; i++) {
                writer.write("Line " + i + "\n");
            }
            // Do I need to call writer.flush() here explicitly?
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Questions:

  1. Is it necessary to call writer.flush() explicitly before closing the BufferedWriter?

  2. Are there performance differences between calling flush() periodically inside the loop vs relying on try-with-resources?

  3. What are the recommended best practices for writing large files efficiently in Java?

New contributor
Ahamed Shahif is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.

1 Answer 1

0

tl;dr

BufferedWriter in your try-with-resources syntax handles all your concerns about efficiency and flushing. Nothing more for you to do.

Don’t worry. Be happy.

It is the job of a BufferedWriter implementation to efficiently handle writing data to a file. No need for you to worry. So your Question is effectively moot; just let the buffered writer do its job.

Notice that BufferedWriter is AutoCloseable (sic). That means you can conveniently use it in try-with-resources syntax as shown in your example code. When the task has completed, and flow-of-control exits your try block, the JVM automatically calls the required close method on the resource (your BufferedWriter object).

If we examine the Javadoc for BufferedWriter#close, we see:

Closes the stream, flushing it first.

So the no need for you to do any calls to flush. The BufferedWriter class handle flushing as you submit data. And BufferedWriter#close handles the final flushing when you are done. Easy-peasy.

Java NIO.2

By the way, we can simplify your code using the NIO.2 features in modern Java. Learn about the Path and Files (plural) classes.

And we can make your limit number more readable with digit grouping.

try (
        final BufferedWriter writer = Files.newBufferedWriter( Path.of( "output.txt" ) )
)
{
    for ( int index = 0 ; index < 100_000 ; index++ )
    {
        writer.write( "Line " + index + "\n" );
    }
}  // The `close` method gets called on each declared resource when exiting this block.
catch ( IOException e )
{
    e.printStackTrace();
}

By the way, you may want to replace your hard-coded "/n" with platform-sensitive code: System.lineSeparator().

Threads

Writing to storage is very slow work for a computer. Your code blocks while waiting for the writes to complete.

So one opportunity for optimizing performance, if you actually have a proven performance problem, is to use virtual threads to prepare your data for export in advance rather than alternating between preparing and writing.

That is much too big a topic to address here. You will find many existing Questions & Answers on that.

Sign up to request clarification or add additional context in comments.

1 Comment

By the way, you may want to replace your hard-coded "/n" with platform-sensitive code: System.lineSeparator(). Or just do writer.newLine(); (which will give you the correct separator for your platform)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.