Writing Text Files in Java
Fast recall
Quick revision
Core answer
Files.writeString for a small complete value or Files.newBufferedWriter for incremental output, always choosing the charset and open options that match create, replace, or append behavior.Interview-ready guide
Interview answer
Java NIO provides two straightforward text-writing styles. Files.writeString(path, text, charset, options) is convenient when the complete, reasonably small string is already in memory. Files.newBufferedWriter(path, charset, options) returns a Writer for producing text incrementally. Both encode Java characters into bytes using the selected charset.
The open options are part of correctness. Without explicit options, these methods create a missing file and truncate an existing file for writing. APPEND keeps existing bytes and adds new output, while CREATE_NEW fails if the target already exists. A program should not rely on an accidental default when overwriting could destroy important data.
For example, a report generator can open a UTF-8 BufferedWriter, write a header, call newLine(), and then write each row as it is produced. Try-with-resources closes the writer on every exit path. Closing also flushes buffered characters through the encoder to the file; calling flush() is useful only when the writer must remain open while another consumer needs current data.
A successful series of writes is not the same as atomic publication. If generation fails after truncating the destination, readers may see a partial report. Important replacement workflows commonly write a sibling temporary file, validate it, and then move it into place, requesting an atomic move only where the file-system provider supports it.
Text writers do not escape CSV, JSON, HTML, or another application format automatically. The application or a format library still owns quoting, schema, and validation. Choose the text API for the output size, choose the charset and file options explicitly, and add a publication strategy when partial output would be harmful.
Writing Text Files in Java
Direct Answer
Write text with Files.writeString for a small complete value or Files.newBufferedWriter for incremental output, always choosing the charset and open options that match create, replace, or append behavior.
Deep Dive & Architecture
A Writer accepts characters, but a file stores bytes. The charset encoder decides which byte sequence is written and how unmappable input is handled. UTF-8 can represent every Unicode code point, which makes it a reliable interchange default, but the reader and writer still need to agree on that encoding. An explicit charset makes the agreement reviewable.
Buffering improves the shape of underlying writes, not the logical format. BufferedWriter.newLine() emits the platform line separator; writing emits a fixed line feed. A cross-platform wire format may require a specific separator, while a local human-readable file may prefer the platform convention. That choice belongs to the format contract.
Append is not record-safe merely because the file is opened with APPEND. Multiple writers, partial records, process crashes, and encoding boundaries can still produce ambiguous output. Applications needing durable logs normally use a logging system that coordinates concurrency, rotation, formatting, and failure handling.
For replace-in-place output, temporary construction narrows the visible failure window. It also creates new decisions: temporary-file location, permissions, cleanup, and fallback when ATOMIC_MOVE is unsupported. A teaching example can show a direct write, but production code should match the stronger guarantees its readers actually require.
Code Example
import java.io.BufferedWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
class WriteTextFile {
public static void main(String[] args) throws Exception {
Path report = Files.createTempFile("report-", ".txt");
try {
try (BufferedWriter writer = Files.newBufferedWriter(report, StandardCharsets.UTF_8)) {
writer.write("name,score");
writer.newLine();
writer.write("Mira,98");
writer.newLine();
}
String text = Files.readString(report, StandardCharsets.UTF_8);
if (!text.contains("Mira,98")) throw new AssertionError(text);
System.out.print(text);
} finally {
Files.deleteIfExists(report);
}
}
}
Check your understanding
Answer these without looking back at the article.
- What do the default Files.newBufferedWriter options do to an existing file?
- When is flush useful before close?
- How would you avoid exposing a partially generated replacement file?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.