Files.readAllLines: примеры (JAVA)
Files.readAllLines(Path path): ListОписание и сигнатуры
Метод Files.readAllLines(Path) и его перегрузка Files.readAllLines(Path, Charset) из пакета java.nio.file предоставляет удобный способ прочитать весь текстовый файл в список строк. В результате возвращается java.util.List<String>, в котором каждая запись соответствует одной строке исходного файла. Разделители строк удаляются при чтении.
Типичные сигнатуры:
static List<String> readAllLines(Path path) throws IOException- использует кодировку по умолчанию (Charset.defaultCharset()).static List<String> readAllLines(Path path, Charset cs) throws IOException- явное указание кодировки.
Возвращаемое значение: список строк, содержащих содержимое файла без символов конца строки. Возвращаемый список реализуется обычно как изменяемый ArrayList, что позволяет далее изменять элементы или добавлять новые.
Исключения и ошибки: при проблемах ввода/вывода бросается IOException (например, NoSuchFileException, AccessDeniedException). В случае очень больших файлов возможен OutOfMemoryError, так как весь файл загружается в память. Может возникнуть SecurityException при ограниченном доступе.
Особенности поведения: метод закрывает файл после чтения. Разделители строк (\n, \r\n, \r) удаляются, характеристики кодировки существенно влияют на корректное чтение, поэтому для контроля кодировки предпочтительна перегрузка с Charset.
Короткие примеры использования
Пример 1. Простое чтение файла с использованием кодировки по умолчанию.
import java.nio.file.*;
import java.io.IOException;
import java.util.List;
Path path = Paths.get("example.txt");
try {
List lines = Files.readAllLines(path);
System.out.println(lines);
} catch (IOException e) {
e.printStackTrace();
}
["Первая строка", "Вторая строка", "Третья строка"]
Пример 2. Чтение с явной кодировкой UTF-8.
import java.nio.charset.StandardCharsets;
List lines = Files.readAllLines(path, StandardCharsets.UTF_8);
System.out.println(lines.get(0));
Первая строка
Пример 3. Чтение пустого файла возвращает пустой список.
List lines = Files.readAllLines(Paths.get("empty.txt"));
System.out.println(lines.size());
0
Пример 4. Поведение при отсутствии файла (короткий пример обработки исключения).
try {
Files.readAllLines(Paths.get("no_such.txt"));
} catch (IOException e) {
System.out.println(e.getClass().getSimpleName() + ": " + e.getMessage());
}
NoSuchFileException: no_such.txt
Похожие API в Java и выбор в пользу них
Files.lines(Path)- возвращает Stream<String> и читает построчно. Предпочтителен для больших файлов или ленивой обработки, позволяет использовать параллельные операции и экономит память.Files.readString(Path)(с Java 11) - возвращает весь файл как одну строку. Удобен при необходимости получить единый текст, но требует дополнительного разбиения на строки.Files.newBufferedReader(Path, Charset)вместе с BufferedReader.readLine() - даёт контроль над чтением, полезно для потоковой обработки и при необходимости обработки больших файлов без загрузки в память.Files.readAllBytes(Path)- возвращает байтовый массив, полезен для бинарных файлов или когда требуется собственная декодировка.
Выбор между ними зависит от размера файла, требований к памяти, желаемой кодировки и необходимости потоковой обработки.
Аналоги в других языках и отличия
Краткий обзор по языкам с примерами.
- Python
# pathlib from pathlib import Path lines = Path('example.txt').read_text(encoding='utf-8').splitlines() print(lines)['Первая строка', 'Вторая строка', 'Третья строка']
Отличие: читается весь текст, затем splitlines удаляет разделители. Есть также Path.read_text и open().readlines(). - JavaScript (Node.js)
const fs = require('fs'); const data = fs.readFileSync('example.txt', 'utf8').split(/\r?\n/); console.log(data);[ 'Первая строка', 'Вторая строка', 'Третья строка' ]
Отличие: синхронное чтение блокирует поток; для больших файлов используется createReadStream. - PHP
$lines = file('example.txt', FILE_IGNORE_NEW_LINES); print_r($lines);Array ( [0] => Первая строка [1] => Вторая строка )
Отличие: функция file возвращает массив строк, можно указать флаг для удаления символов конца строки. - C#
var lines = System.IO.File.ReadAllLines("example.txt"); Console.WriteLine(lines[0]);Первая строка
Отличие: API очень похож, есть File.ReadLines для ленивой обработки. - Go
data, _ := os.ReadFile("example.txt") lines := strings.Split(strings.ReplaceAll(string(data), "\r\n", "\n"), "\n") fmt.Println(lines)[Первая строка Вторая строка Третья строка]
Отличие: читается байтовый слайс, затем декодируется в строку и разбивается. - Kotlin
val lines = java.nio.file.Files.readAllLines(Paths.get("example.txt"), Charsets.UTF_8) println(lines)[Первая строка, Вторая строка]
Отличие: использует те же java.nio интерфейсы, есть kotlin.io.File.readLines удобная обёртка. - Lua
local t = {} for line in io.lines('example.txt') do table.insert(t, line) end for i,v in ipairs(t) do print(v) endПервая строка Вторая строка
Отличие: построчное чтение через итератор; не загружает весь файл в одну структуру по умолчанию.
Основная разница между Java и большинством языков - необходимость явно указать кодировку или учесть системную по умолчанию и нагрузка на память при чтении целиком.
Типичные ошибки и примеры
Ошибка 1. Файл не найден - NoSuchFileException.
try {
Files.readAllLines(Paths.get("missing.txt"));
} catch (IOException e) {
System.out.println(e.getClass().getSimpleName());
}
NoSuchFileException
Ошибка 2. Проблемы доступа - AccessDeniedException или SecurityException.
// при попытке читать файл без прав
try {
Files.readAllLines(Paths.get("/root/secret.txt"));
} catch (IOException e) {
System.out.println(e.getClass().getSimpleName());
}
AccessDeniedException
Ошибка 3. Переполнение памяти при очень большом файле.
// гипотетический пример большого файла
List lines = Files.readAllLines(Paths.get("huge.txt"));
// может привести к OutOfMemoryError при недостатке памяти
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
Ошибка 4. Неправильная кодировка приводит к искажениям символов.
List lines = Files.readAllLines(path, StandardCharsets.ISO_8859_1);
// если файл в UTF-8, появятся некорректные символы
ÃÂõúðÿ
Изменения и эволюция API
Метод Files.readAllLines введён в Java 7 вместе с NIO.2. С выходом Java 11 появились новые удобные методы: Files.readString и Files.writeString для чтения/записи текста как одной строки с использованием UTF-8 по умолчанию в их сигнатурах без явной кодировки. Поведение readAllLines в отношении удаления разделителей строк и возвращаемого списка осталось стабильным; изменений в семантике не отмечено.
Расширенные и редкие сценарии применения
Пример 1. Чтение файла в zip-архиве через FileSystem (чтение как обычного файла).
import java.nio.file.*;
import java.util.*;
import java.io.IOException;
Map env = new HashMap<>();
env.put("create", "false");
try (FileSystem fs = FileSystems.newFileSystem(Paths.get("archive.zip"), null)) {
Path p = fs.getPath("docs/example.txt");
List lines = Files.readAllLines(p, StandardCharsets.UTF_8);
System.out.println(lines.size());
}
3
Пример 2. Преобразование результата в поток для дальнейшей обработки без повторного чтения файла.
List lines = Files.readAllLines(path, StandardCharsets.UTF_8);
long nonEmpty = lines.stream()
.map(String::trim)
.filter(s -> !s.isEmpty())
.count();
System.out.println(nonEmpty);
2
Пример 3. Создание неизменяемого представления и кэширование содержимого.
List cached = Collections.unmodifiableList(Files.readAllLines(path, StandardCharsets.UTF_8));
// cached нельзя изменить, можно безопасно передать в другие модули
[Первая строка, Вторая строка]
Пример 4. Обработка больших файлов с контролем памяти: сравнение с Files.lines.
// Небезопасно для больших файлов
try {
List all = Files.readAllLines(bigPath);
} catch (OutOfMemoryError e) {
System.out.println("Недостаточно памяти для чтения целиком");
}
// Рекомендация: использовать поток
try (Stream stream = Files.lines(bigPath)) {
long count = stream.filter(l -> !l.trim().isEmpty()).count();
System.out.println(count);
}
Недостаточно памяти для чтения целиком 123456
Пример 5. Чтение и восстановление исходных разделителей строк (если требуется): сначала прочитать байты, затем анализировать.
byte[] data = Files.readAllBytes(path);
String text = new String(data, StandardCharsets.UTF_8);
// вручную разделить и сохранить разделители
List parts = new ArrayList<>();
Matcher m = Pattern.compile("(.*?)(\r\n|\n|\r|$)", Pattern.DOTALL).matcher(text);
while (m.find()) parts.add(m.group(1) + m.group(2));
System.out.println(parts.get(0));
Первая строка\n
Пример 6. Сочетание с parallelStream для распараллеливания постобработки (внимание к потоко-безопасности).
List lines = Files.readAllLines(path);
Map map = lines.parallelStream()
.map(String::length)
.collect(Collectors.groupingByConcurrent(Integer::intValue, Collectors.counting()));
System.out.println(map);
{5=2, 12=1}
Примеры демонстрируют, как readAllLines может использоваться в разных задачах, и когда стоит предпочесть ленивый поток либо побайтовое чтение.