middle
Как работать с файлами и каталогами через Files API?
Класс java.nio.file.Files предоставляет исчерпывающий набор статических методов для работы с файлами и каталогами, покрывающий все основные сценарии: чтение, запись, копирование, удаление, создание каталогов, обход дерева и проверку атрибутов.
Чтение и запись файлов
Примеры чтения и записи
Path path = Path.of("example.txt");
// Запись строки в файл (Java 11+)
Files.writeString(path, "Привет, мир!\nВторая строка.", StandardCharsets.UTF_8);
// Запись списка строк
Files.write(path, List.of("строка 1", "строка 2"), StandardCharsets.UTF_8);
// Дозапись в файл
Files.writeString(path, "\nДополнение",
StandardCharsets.UTF_8, StandardOpenOption.APPEND);
// Чтение всего содержимого (Java 11+)
String content = Files.readString(path, StandardCharsets.UTF_8);
// Чтение построчно в список
List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8);
// Ленивое чтение через Stream (для больших файлов)
try (Stream<String> stream = Files.lines(path)) {
stream.filter(l -> l.contains("ERROR")).forEach(System.out::println);
}
Копирование, перемещение и удаление
Примеры операций с файлами
Path source = Path.of("source.txt");
Path target = Path.of("backup/source_copy.txt");
// Копирование с заменой существующего
Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
// Копирование из InputStream в файл
try (InputStream is = new URL("https://example.com/file.txt").openStream()) {
Files.copy(is, target, StandardCopyOption.REPLACE_EXISTING);
}
// Атомарное перемещение
Files.move(source, target, StandardCopyOption.ATOMIC_MOVE);
// Удаление
Files.delete(path); // бросает NoSuchFileException
Files.deleteIfExists(path); // возвращает false
Создание каталогов и временных файлов
Пример
Files.createDirectory(Path.of("new_dir")); // один каталог
Files.createDirectories(Path.of("a/b/c/d")); // вложенные (mkdir -p)
Path tempFile = Files.createTempFile("prefix_", ".tmp");
Path tempDir = Files.createTempDirectory("my_temp_");
Обход дерева каталогов
Примеры обхода
// Files.list — только первый уровень
try (Stream<Path> stream = Files.list(Path.of("src"))) {
stream.filter(Files::isRegularFile).forEach(System.out::println);
}
// Files.walk — рекурсивный обход
try (Stream<Path> stream = Files.walk(Path.of("/project/src"))) {
List<Path> javaFiles = stream
.filter(Files::isRegularFile)
.filter(p -> p.toString().endsWith(".java"))
.collect(Collectors.toList());
}
// Files.walkFileTree — продвинутый обход (например, рекурсивное удаление)
Files.walkFileTree(Path.of("dir_to_delete"), new SimpleFileVisitor<>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException {
Files.delete(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc)
throws IOException {
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
});
Проверка свойств файлов
Пример
boolean exists = Files.exists(path);
boolean isFile = Files.isRegularFile(path);
boolean isDir = Files.isDirectory(path);
boolean isLink = Files.isSymbolicLink(path);
long size = Files.size(path);
String mimeType = Files.probeContentType(path); // "text/plain"
Важное
- Все методы
Files, возвращающиеStream(list(),walk(),find(),lines()), требуютtry-with-resources. Files.createDirectories()не бросает исключение, если каталог уже существует.DirectoryStream— этоIterable, а неStreamиз Java 8.- Для рекурсивного удаления каталога необходим обход через
walkFileTree—Files.delete()не удаляет непустой каталог.
На собеседовании: продемонстрируйте знание основных операций: чтение/запись, обход дерева, копирование/перемещение. Упомяните обязательность
try-with-resourcesдля Stream-методов и невозможность удалить непустой каталог одним вызовом.