Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Файлы и пути

Для работы с файлами в современной Java есть два главных инструмента из пакета java.nio.file. Path — это путь к файлу или папке, просто адрес, который может и не существовать. Files — набор статических методов, которые что-то делают с файлами: создают, копируют, удаляют, читают.

Путь

Путь создают методом Path.of. Части можно передать по отдельности — Java сама соединит их разделителем, принятым в операционной системе:

void main() {
    Path path = Path.of("docs", "2026", "report.txt");
 
    IO.println(path.getFileName());
    IO.println(path.getParent().getFileName());
}

Результат:

report.txt
2026

Путь docs/2026/report.txt — относительный: он отсчитывается от текущей папки, из которой запущена программа. Абсолютный путь начинается от корня диска, его возвращает toAbsolutePath(). Все примеры этого урока используют относительные пути и сами создают нужные файлы.

Существует ли файл

Сам Path ничего не знает о диске. Чтобы проверить файл, нужен класс Files:

void main() throws IOException {
    Path path = Path.of("hello.txt");
    IO.println(Files.exists(path));
 
    Files.writeString(path, "Привет!");
    IO.println(Files.exists(path));
    IO.println(Files.size(path) + " байт");
}

Результат:

false
true
13 байт

Files.writeString создаёт файл и записывает в него строку. Размер — 13 байт: латинские буквы в кодировке UTF-8 занимают по байту, а русские — по два.

Папки

Files.createDirectories создаёт папку вместе со всеми недостающими родительскими. Files.isDirectory и Files.isRegularFile отличают папку от обычного файла:

void main() throws IOException {
    Path dir = Path.of("photos", "summer");
    Files.createDirectories(dir);
 
    Path photo = dir.resolve("sea.jpg");
    Files.writeString(photo, "...");
 
    IO.println(photo);
    IO.println(Files.isDirectory(dir));
    IO.println(Files.isRegularFile(photo));
}

Результат (на Windows разделитель — \):

photos/summer/sea.jpg
true
true

Метод resolve добавляет к пути ещё одну часть — это удобнее, чем склеивать строки вручную.

Копирование, перемещение, удаление

void main() throws IOException {
    Path original = Path.of("notes.txt");
    Files.writeString(original, "План на неделю");
 
    Path copy = Files.copy(original, Path.of("notes-copy.txt"), StandardCopyOption.REPLACE_EXISTING);
    Path moved = Files.move(copy, Path.of("archive.txt"), StandardCopyOption.REPLACE_EXISTING);
 
    IO.println(Files.exists(copy));
    IO.println(Files.readString(moved));
 
    Files.delete(moved);
    IO.println(Files.exists(moved));
}

Результат:

false
План на неделю
false

Без StandardCopyOption.REPLACE_EXISTING методы copy и move выбрасывают исключение, если целевой файл уже есть. Files.deleteIfExists удаляет файл без ошибки, если его нет.

Список файлов

Files.list возвращает поток путей внутри папки. Порядок файлов зависит от операционной системы, поэтому результат лучше отсортировать. Поток держит папку открытой, так что его закрывают через try-with-resources:

void main() throws IOException {
    Path dir = Files.createDirectories(Path.of("inbox"));
    for (String name : List.of("b.txt", "a.txt", "c.log")) {
        Files.writeString(dir.resolve(name), name);
    }
 
    try (Stream<Path> files = Files.list(dir)) {
        files.map(p -> p.getFileName().toString())
                .filter(name -> name.endsWith(".txt"))
                .sorted()
                .forEach(IO::println);
    }
}

Результат:

a.txt
b.txt

Чтобы обойти и все вложенные папки, используйте Files.walk — он работает так же, но спускается вглубь.

Частая ошибка

Files.delete не удаляет непустую папку — сначала нужно удалить всё, что внутри:

void main() throws IOException {
    Path dir = Files.createDirectories(Path.of("tmp"));
    Files.writeString(dir.resolve("data.txt"), "1");
 
    Files.delete(dir);
}

Результат:

Exception in thread "main" java.nio.file.DirectoryNotEmptyException: tmp
	at Main.main(Main.java:5)

Удаляйте содержимое, а потом саму папку. Для дерева папок обходите его через Files.walk в обратном порядке, чтобы файлы удалялись раньше своих папок.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.