Чтение текстового файла в Java: пошаговое руководство для начинающих
import java.io.*;
public class ReadFile {
public static void main(String[] args) {
File file = new File("data.txt");
Scanner scanner = new Scanner(file);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
System.out.println(line);
}
scanner.close();
}
}
Этот код выдаёт ошибку "FileNotFoundException", хотя файл лежит в той же папке, что и исходник. Потом я нашёл пример с BufferedReader и FileReader, но там нужно обрабатывать исключения, и я запутался в try-catch. Ещё видел, что в Java 8 можно использовать Files.lines(), но это вообще магия какая-то.
Подскажите, пожалуйста, как правильно и безопасно читать текстовые файлы в Java? Мне нужно понять: 1) Как указать путь к файлу, чтобы он точно нашёлся? 2) Как правильно закрывать ресурсы, чтобы не было утечек? 3) Какой способ самый надёжный для начинающего? Буду благодарен за подробное объяснение с примерами кода, которые можно скопировать и запустить.
P.S. Если это важно — файл небольшой, около 100 строк, кодировка UTF-8.
<<Классический способ: BufferedReader + FileReader (Java 7+)
Самый надёжный и понятный метод для начинающих — использовать BufferedReader в связке с FileReader. Главное преимущество — вы читаете файл построчно, а не целиком, что экономит память.
import java.io.*;
public class ReadFileExample {
public static void main(String[] args) {
// Укажите полный путь или относительный (от корня проекта)
String filePath = "data.txt";
// try-with-resources автоматически закроет файл
try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
System.err.println("Ошибка чтения файла: " + e.getMessage());
}
}
}
Почему это работает?
- FileReader открывает файл для чтения символов (с учётом кодировки по умолчанию).
- BufferedReader оборачивает FileReader и добавляет буферизацию — читает данные большими блоками, а не по одному символу.
- Конструкция try-with-resources (появилась в Java 7) гарантирует, что ресурс (
BufferedReader) будет закрыт автоматически, даже если возникнет исключение.
Как указать путь к файлу?
Есть три варианта:
- Относительный путь — от корня проекта (папки, где лежит src). Пример:
"data.txt"или"resources/data.txt". - Абсолютный путь — полный путь на диске:
"C:/Users/User/project/data.txt"(для Windows) или"/home/user/project/data.txt"(для Linux/Mac). - Через ClassLoader — если файл лежит внутри JAR или в classpath:
getClass().getClassLoader().getResourceAsStream("data.txt").
Совет: всегда проверяйте, существует ли файл, с помощью new File("путь").exists() перед чтением.
Учёт кодировки (UTF-8)
Если ваш файл в UTF-8, используйте InputStreamReader вместо FileReader:
try (BufferedReader br = new BufferedReader(
new InputStreamReader(new FileInputStream(filePath), "UTF-8"))) {
// чтение такое же
}
Что делать с FileNotFoundException?
Ошибка возникает, если файл не найден. Проверьте:
- Текущую рабочую директорию (выведите
System.getProperty("user.dir")). - Расширение файла (например,
.txt). - Права доступа к файлу.
В примере выше исключение перехватывается блоком catch, и программа не падает.
Альтернатива для Java 8+: Files.lines()
Если вы используете Java 8 или новее, есть более лаконичный способ через Stream API:
import java.nio.file.*;
import java.util.stream.*;
public class ReadFileStream {
public static void main(String[] args) throws IOException {
// Files.lines() возвращает Stream строк
try (Stream<String> lines = Files.lines(Paths.get("data.txt"))) {
lines.forEach(System.out::println);
}
}
}
Этот метод тоже использует try-with-resources и автоматически закрывает файл. Он идеален, если нужно обработать строки (например, отфильтровать или преобразовать).
Итог: что выбрать новичку?
Начните с BufferedReader + FileReader — это классика, которая работает везде и легко понимается. Когда освоитесь, переходите к Files.lines() для более современного стиля.
Простой способ для маленьких файлов: Files.readAllLines()
Если ваш файл небольшой (до нескольких мегабайт) и вы хотите получить все строки сразу в виде списка, используйте статический метод Files.readAllLines() из пакета java.nio.file. Это самый короткий и понятный вариант для начинающих.
import java.nio.file.*;
import java.util.*;
import java.io.IOException;
public class SimpleRead {
public static void main(String[] args) {
try {
List<String> lines = Files.readAllLines(Paths.get("data.txt"));
for (String line : lines) {
System.out.println(line);
}
} catch (IOException e) {
System.err.println("Ошибка: " + e.getMessage());
}
}
}
Плюсы и минусы
- Плюсы: минимальный код, не нужно заботиться о буферизации или закрытии ресурсов — метод делает всё сам. Поддерживает кодировку UTF-8 по умолчанию.
- Минусы: файл загружается в память целиком. Для больших файлов (сотни мегабайт) это может вызвать проблемы с памятью.
Когда использовать?
Этот способ идеален для конфигурационных файлов, логов небольшого размера или учебных примеров. Если вы только учитесь — начните с него, а потом переходите к более продвинутым методам.
Обратите внимание: метод readAllLines возвращает List<String>, поэтому вы можете легко обращаться к любой строке по индексу, например lines.get(0) для первой строки.