Arbeit mit Dateien in Java: Ausführliches Handbuch
What is this and why? (a real-life analogy)
Imagine you are writing an essay in a notebook. While you are writing, the information is in your head and at the tip of the pen. But as soon as you close the notebook and put it in your backpack, the information is saved. Tomorrow you will open the notebook again and continue writing. The same thing happens in programming: while the program is running, all data lives in RAM (like in your head). As soon as the program closes, the memory is cleared. To keep data forever, you need to save it to a file (like in a notebook).
Working with files in Java is the program's ability to read information from files (for example, opening a saved game) and write information to files (saving progress). Without this, any program would be "memoryless": every launch would start from scratch.
💡 Important: Files come in different types: text files (.txt, .csv, .json), binary files (images, music, archives). In this article, we will focus on text files — this is the absolute basics.
Theory: how it works internally
To read a file, Java must go through several stages:
- Open the "door" to the file — create an object that points to the desired file on the hard drive.
- Create a "pipe" for reading — a special stream object that can retrieve data from the file.
- Read data in pieces — either one character at a time, line by line, or as entire arrays.
- Close the "pipe" — mandatory! Otherwise, the file will remain locked, and other programs will not be able to access it.
In Java, there are two main approaches to reading files:
| Approach | Essence | When to use |
|---|---|---|
| Byte Streams (InputStream) | Reads the file as a set of bytes (0s and 1s) | For images, music, video — any non-text data |
| Character Streams (Reader) | Reads the file as text, considering encoding (UTF-8, Windows-1251) | For text files — documents, configs, logs |
In this article, we will work with character streams, as they are more convenient for reading text.
The main classes for reading text files in Java:
| Class | Purpose | Feature |
|---|---|---|
FileReader |
Basic character reading from a file | Works with the default encoding (may be problematic with Russian text) |
BufferedReader |
Reading with buffering (accumulating data in memory) | 10-100 times faster than FileReader, can read entire lines |
Scanner |
Convenient reading with parsing into words and numbers | Slower than BufferedReader, but more convenient for small files |
Files.readAllLines() |
Reading the entire file at once into a list of strings | Convenient, but not suitable for huge files (consumes a lot of memory) |
Syntax in Java: all forms and variants
Let's break down three main ways to read a file. Each method has its pros and cons.
Method 1: Classic — FileReader + BufferedReader
This is the "grandfather" method that has been working in Java since the very first version. It is reliable, fast, and understandable.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class ClassicRead {
public static void main(String[] args) {
// Create a variable for the reader outside the try block
BufferedReader reader = null;
try {
// Step 1: Open the file
FileReader fileReader = new FileReader("input.txt");
// Step 2: Wrap it in a buffered reader for speed
reader = new BufferedReader(fileReader);
// Step 3: Read the first line
String line = reader.readLine();
// Step 4: While the line is not empty (not null) — keep reading
while (line != null) {
System.out.println(line); // Print the line to the screen
line = reader.readLine(); // Read the next line
}
} catch (IOException e) {
// If something goes wrong — catch the error
System.err.println("Error reading file: " + e.getMessage());
} finally {
// Step 5: IMPORTANT! Close the reader in the finally block
// This guarantees closure even if an error occurred
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
System.err.println("Error closing file: " + e.getMessage());
}
}
}
}
⚠️ Note: The finally block always executes — both after successful reading and after an error. This guarantees that the file will be closed.
Method 2: Modern — try-with-resources (Java 7+)
Starting with Java 7, a more elegant method was introduced. The resource (file) is automatically closed when we exit the try block. There is less code, and reliability is higher.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class TryWithResourcesRead {
public static void main(String[] args) {
// The resource is declared in parentheses after try
// Java will close it automatically upon exiting the block
try (BufferedReader reader = new BufferedReader(new FileReader("input.txt"))) {
String