middle
Что такое NIO.2 и чем он отличается от java.io.File?
NIO.2 (пакет java.nio.file) — это API для работы с файловой системой, появившееся в Java 7 как замена устаревшему классу java.io.File. Центральные элементы — интерфейс Path и утилитный класс Files.
Path vs File
Path — это интерфейс, представляющий путь в файловой системе. Объекты Path являются неизменяемыми (immutable), что обеспечивает потокобезопасность и предсказуемость.
Пример
// Старый подход — java.io.File
File file = new File("/home/user/data.txt");
// Новый подход — java.nio.file.Path
Path path = Path.of("/home/user/data.txt"); // Java 11+
Path path2 = Paths.get("/home/user/data.txt"); // Java 7+
Path path3 = Path.of("/home", "user", "data.txt"); // составной путь
Основные отличия
| Характеристика | java.io.File | java.nio.file.Path + Files |
|---|---|---|
| Тип | Класс | Path — интерфейс |
| Иммутабельность | Нет | Да |
| Обработка ошибок | Возвращает false/null |
Бросает информативные исключения (NoSuchFileException, AccessDeniedException) |
| Символьные ссылки | Ограниченная поддержка | Полная поддержка |
| Метаданные файлов | Ограниченный набор | Полный набор атрибутов через Files.readAttributes() |
| Обход дерева | Ручная рекурсия | Files.walk(), Files.walkFileTree() |
| Stream API | Нет | Files.lines(), Files.list(), Files.walk() |
Класс Files
Files предоставляет статические методы для всех операций с файлами и каталогами.
Примеры работы с Files
// Чтение и запись (Java 11+)
String content = Files.readString(Path.of("file.txt"));
Files.writeString(Path.of("output.txt"), "Содержимое", StandardCharsets.UTF_8);
// Чтение и запись (Java 7+)
byte[] bytes = Files.readAllBytes(Path.of("file.txt"));
List<String> lines = Files.readAllLines(Path.of("file.txt"), StandardCharsets.UTF_8);
// Ленивое чтение строк (возвращает Stream)
try (Stream<String> stream = Files.lines(Path.of("large_file.txt"))) {
stream.filter(line -> line.contains("ERROR"))
.forEach(System.out::println);
}
// Обход дерева каталогов
try (Stream<Path> paths = Files.walk(Path.of("/home/user"))) {
paths.filter(Files::isRegularFile)
.filter(p -> p.toString().endsWith(".java"))
.forEach(System.out::println);
}
// Копирование, перемещение, удаление
Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
Files.move(source, target, StandardCopyOption.ATOMIC_MOVE);
Files.deleteIfExists(path);
Преобразование между File и Path
Пример
File file = new File("data.txt");
Path path = file.toPath(); // File -> Path
Path path2 = Path.of("data.txt");
File file2 = path2.toFile(); // Path -> File
Частые ошибки
- Забывают закрывать
StreamотFiles.lines()иFiles.walk()— утечка файловых дескрипторов. - Используют
Files.readAllLines()для огромных файлов — весь файл загружается в память. - Не указывают
StandardCopyOption.REPLACE_EXISTINGпри копировании. - Путают
Files.delete()(бросает исключение) иFiles.deleteIfExists()(возвращает boolean).
На собеседовании: назовите ключевые преимущества NIO.2: иммутабельный Path, информативные исключения, полная поддержка символьных ссылок, интеграция со Stream API. Использование
java.io.Fileв новом коде считается устаревшей практикой.