What is the simplest modern way to read all text from a small file and write text to a file in Java, and what should you watch out for?
answer
- Files.readString / writeString (Java 11+)
- readAllLines -> List<String>
- UTF-8 default; whole file into memory
- small files only; write truncates unless APPEND
- throws IOException (checked)
basics
~20 sUse the Files helper class: Files.readString(path) reads the whole file into one String, and Files.writeString(path, text) writes a String to a file. Both are fine for small files only, because they load everything into memory at once.
solid answer
~40 sSince Java 11 the easiest way is java.nio.file.Files. Files.readString(Path) returns the entire file as one String, and Files.writeString(Path, CharSequence, OpenOption...) writes a String out. For lines, Files.readAllLines(Path) gives a List<String> and Files.write(Path, Iterable<String>) writes them back. These one-liners default to UTF-8 (Java 18+ makes UTF-8 the platform default too), and they open and close the file for you, so there is no resource leak. The big caveat: they read the whole file into memory, so they only suit small-to-moderate files. For large files you stream line by line with Files.lines or a BufferedReader. Writing replaces the file by default unless you pass StandardOpenOption.APPEND.
go deeper
Knows Files.readString/writeString and readAllLines exist and that they handle small files end to end.
Knows the UTF-8 default, the memory caveat, and write-truncates-by-default vs APPEND.
Articulates the pre-Java-18 platform-default-charset pitfall and chooses streaming vs whole-file deliberately based on size.
Sets team conventions (always explicit charset, size thresholds, OpenOption discipline) and understands the Java 18 UTF-8 default migration impact across the codebase.
## The problem Reading and writing text files is one of the most common I/O tasks. A *text file* is just bytes on disk that represent characters according to an *encoding* (a mapping between characters and byte sequences, e.g. UTF-8). To turn bytes into a Java String you must decode them with the right encoding; to write a String you encode it back to bytes. ## The tools Java has several layers: - **`java.io`** (old): `FileReader`/`FileWriter`, `BufferedReader`/`BufferedWriter` — stream-based, manual resource management. - **`java.nio.file`** (newer, since Java 7, expanded in 11): the **`Files`** utility class plus **`Path`** (an object describing a file location, created via `Path.of("...")` or `Paths.get("...")`). ## The easy helpers (Java 11+) ```java Path p = Path.of("notes.txt"); String all = Files.readString(p); // whole file -> one String Files.writeString(p, "hello\nworld\n"); // write a String, replacing the file List<String> lines = Files.readAllLines(p); // each line as a List entry Files.write(p, lines); // write a List of lines back ``` These methods **open the file, do the work, and close it automatically**, so you cannot leak a file handle. That is their main appeal over the old API where you had to close streams yourself. ## Encoding A *charset* is the character encoding. `Files.readString`/`writeString` use **UTF-8** by default. From **Java 18** UTF-8 is also the JVM-wide default charset (`file.encoding`), so older APIs like `FileReader` that previously used the platform default now also default to UTF-8. Before Java 18, the platform default could be Windows-1252 on Windows or UTF-8 on Linux, causing files to read differently on different machines — a classic bug. Always be explicit about charset when correctness matters. ## The big caveat: memory `readString` and `readAllLines` load the **entire file into memory**. For a multi-gigabyte log this throws `OutOfMemoryError`. They are for *small* files (config, small data). For large files, stream line by line (`Files.lines` or `BufferedReader`). ## Write semantics `Files.writeString`/`Files.write` **truncate and replace** the file by default (they pass `CREATE`, `WRITE`, `TRUNCATE_EXISTING`). To append, pass `StandardOpenOption.APPEND`. To fail if the file already exists, pass `StandardOpenOption.CREATE_NEW`. ## Checked exceptions All of these throw `java.io.IOException` (a *checked* exception — the compiler forces you to handle or declare it), so you wrap them in try/catch or add `throws IOException`.
- When should you NOT use Files.readString?When the file may be large — it loads everything into memory and can throw OutOfMemoryError. Stream line by line instead.
- How do you append instead of overwrite with Files.writeString?Pass StandardOpenOption.APPEND as a trailing OpenOption argument; otherwise the file is truncated and replaced.
saying these in an interview costs you the question
- Using readString/readAllLines on huge files (OOM)
- Assuming the platform default charset is always UTF-8 before Java 18
- Forgetting these methods overwrite the file unless APPEND is passed
- Thinking you must manually close anything with the Files helpers