JavaRush /Курсы /JAVA 25 SELF /Получение и изменение атрибутов файлов

Получение и изменение атрибутов файлов

JAVA 25 SELF
39 уровень , 4 лекция
Открыта

1. Чтение базовых атрибутов: BasicFileAttributes

Когда мы говорим о файле или папке, мы имеем в виду не только его имя или размер. У каждого файла есть «паспорт» — набор атрибутов, который содержит:

  • Время создания
  • Время последнего изменения
  • Время последнего доступа
  • Размер
  • Права доступа (кто может читать, писать, выполнять)
  • Информация о владельце (на Unix)
  • Признаки «скрытый», «только для чтения» и др.

В Java для работы с этими атрибутами есть удобный и мощный API в пакете java.nio.file.attribute. Не нужно писать платформозависимый код: всё необходимое есть в стандартной библиотеке.

Для начала — импортируем нужные классы:

import java.nio.file.*;
import java.nio.file.attribute.*;
import java.io.IOException;

Как получить базовые атрибуты файла?

Используем метод Files.readAttributes:

Path path = Paths.get("example.txt");
try {
    BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);

    System.out.println("Создан: " + attrs.creationTime());
    System.out.println("Изменён: " + attrs.lastModifiedTime());
    System.out.println("Последний доступ: " + attrs.lastAccessTime());
    System.out.println("Размер: " + attrs.size());
    System.out.println("Это директория? " + attrs.isDirectory());
    System.out.println("Это файл? " + attrs.isRegularFile());
    System.out.println("Это символическая ссылка? " + attrs.isSymbolicLink());
} catch (IOException e) {
    System.out.println("Ошибка при чтении атрибутов: " + e.getMessage());
}

Представьте, что вы инспектор и пришли проверить квартиру. Вы не только смотрите, есть ли дверь (файл существует), но и спрашиваете у жильцов: «Когда построили дом? Когда последний раз делали ремонт? Кто хозяин?».

Кратко о свойствах BasicFileAttributes

Свойство Что возвращает?
creationTime()
Дата и время создания файла/папки
lastModifiedTime()
Дата и время последнего изменения
lastAccessTime()
Дата и время последнего доступа
size()
Размер файла (в байтах)
isDirectory()
Это директория?
isRegularFile()
Это обычный файл?
isSymbolicLink()
Это символическая ссылка?

2. Расширенные атрибуты: POSIX и DOS

POSIX-атрибуты (Linux, macOS и другие Unix-подобные ОС)

Если вы работаете на Unix-системе, можно получить расширенную информацию: права доступа, владелец, группа.

try {
    PosixFileAttributes posixAttrs = Files.readAttributes(path, PosixFileAttributes.class);
    System.out.println("Владелец: " + posixAttrs.owner().getName());
    System.out.println("Группа: " + posixAttrs.group().getName());
    System.out.println("Права доступа: " + PosixFilePermissions.toString(posixAttrs.permissions()));
} catch (UnsupportedOperationException e) {
    System.out.println("POSIX-атрибуты не поддерживаются на этой ОС.");
} catch (IOException e) {
    System.out.println("Ошибка при чтении POSIX-атрибутов: " + e.getMessage());
}

Примечание: На Windows этот код выбросит UnsupportedOperationException — это нормально.

DOS-атрибуты (Windows)

На Windows можно работать с признаками «только для чтения», «скрытый», «архивный», «системный»:

try {
    DosFileAttributes dosAttrs = Files.readAttributes(path, DosFileAttributes.class);
    System.out.println("Скрытый: " + dosAttrs.isHidden());
    System.out.println("Только для чтения: " + dosAttrs.isReadOnly());
    System.out.println("Системный: " + dosAttrs.isSystem());
    System.out.println("Архивный: " + dosAttrs.isArchive());
} catch (UnsupportedOperationException e) {
    System.out.println("DOS-атрибуты не поддерживаются на этой ОС.");
} catch (IOException e) {
    System.out.println("Ошибка при чтении DOS-атрибутов: " + e.getMessage());
}

3. Изменение атрибутов файлов

Читать чужие паспорта — это одно, а вот менять дату рождения или фамилию — другое дело! В Java мы можем менять атрибуты файлов (разумеется, с нужными правами).

Изменение времени последней модификации

import java.nio.file.attribute.FileTime;

Path file = Paths.get("example.txt");
try {
    FileTime newTime = FileTime.fromMillis(System.currentTimeMillis() - 24 * 60 * 60 * 1000); // минус 1 день
    Files.setLastModifiedTime(file, newTime);
    System.out.println("Время последней модификации изменено!");
} catch (IOException e) {
    System.out.println("Ошибка при изменении времени: " + e.getMessage());
}

Изменение прав доступа (POSIX)

Только для Unix-систем! Например, сделать файл исполняемым для всех:

try {
    Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rwxr-xr-x");
    Files.setPosixFilePermissions(file, perms);
    System.out.println("Права доступа изменены!");
} catch (UnsupportedOperationException e) {
    System.out.println("POSIX-права не поддерживаются на этой ОС.");
} catch (IOException e) {
    System.out.println("Ошибка при изменении прав: " + e.getMessage());
}

Пояснение к строке "rwxr-xr-x":

  • r — read (чтение)
  • w — write (запись)
  • x — execute (исполнение)
  • Первый блок из 3 символов — владелец, второй — группа, третий — остальные.

Изменение скрытого/только для чтения статуса (DOS-атрибуты, Windows)

Сделать файл скрытым:

try {
    Files.setAttribute(file, "dos:hidden", true);
    System.out.println("Файл стал скрытым (Windows)!");
} catch (UnsupportedOperationException e) {
    System.out.println("DOS-атрибуты не поддерживаются на этой ОС.");
} catch (IOException e) {
    System.out.println("Ошибка при изменении атрибута: " + e.getMessage());
}

Сделать файл «только для чтения»:

try {
    Files.setAttribute(file, "dos:readonly", true);
    System.out.println("Файл теперь только для чтения (Windows)!");
} catch (UnsupportedOperationException e) {
    System.out.println("DOS-атрибуты не поддерживаются на этой ОС.");
} catch (IOException e) {
    System.out.println("Ошибка при изменении атрибута: " + e.getMessage());
}

4. Проверка прав доступа

Иногда важно быстро проверить, можно ли открыть файл для чтения, записи или исполнения:

Path file = Paths.get("example.txt");
System.out.println("Чтение разрешено: " + Files.isReadable(file));
System.out.println("Запись разрешена: " + Files.isWritable(file));
System.out.println("Исполнение разрешено: " + Files.isExecutable(file));

Это работает одинаково на всех платформах, хотя реальное поведение зависит от ОС и настроек безопасности.

5. Практика: вывод подробной информации о файле

Напишем мини-программу, которая по пути к файлу покажет максимум информации и попробует изменить некоторые атрибуты.

import java.nio.file.*;
import java.nio.file.attribute.*;
import java.util.Set;
import java.io.IOException;

public class FileAttributesDemo {
    public static void main(String[] args) throws IOException {
        Path path = Paths.get("example.txt");

        if (!Files.exists(path)) {
            System.out.println("Файл не найден!");
            return;
        }

        // Базовые атрибуты
        BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
        System.out.println("Имя: " + path.getFileName());
        System.out.println("Путь: " + path.toAbsolutePath());
        System.out.println("Размер: " + attrs.size() + " байт");
        System.out.println("Создан: " + attrs.creationTime());
        System.out.println("Изменён: " + attrs.lastModifiedTime());
        System.out.println("Последний доступ: " + attrs.lastAccessTime());
        System.out.println("Это директория? " + attrs.isDirectory());
        System.out.println("Это файл? " + attrs.isRegularFile());

        // Проверка прав доступа
        System.out.println("Чтение разрешено: " + Files.isReadable(path));
        System.out.println("Запись разрешена: " + Files.isWritable(path));
        System.out.println("Исполнение разрешено: " + Files.isExecutable(path));

        // Попробуем изменить время модификации
        FileTime now = FileTime.fromMillis(System.currentTimeMillis());
        Files.setLastModifiedTime(path, now);
        System.out.println("Время последней модификации обновлено!");

        // Попробуем сделать файл скрытым (если поддерживается)
        try {
            Files.setAttribute(path, "dos:hidden", true);
            System.out.println("Файл стал скрытым (если поддерживается ОС).");
        } catch (UnsupportedOperationException e) {
            System.out.println("Скрытые файлы не поддерживаются на этой ОС.");
        }

        // Попробуем вывести POSIX-права (если поддерживается)
        try {
            PosixFileAttributes posixAttrs = Files.readAttributes(path, PosixFileAttributes.class);
            System.out.println("Владелец: " + posixAttrs.owner().getName());
            System.out.println("Права доступа: " + PosixFilePermissions.toString(posixAttrs.permissions()));
        } catch (UnsupportedOperationException e) {
            System.out.println("POSIX-атрибуты не поддерживаются на этой ОС.");
        }
    }
}

6. Полезные нюансы

Кроссплатформенные различия и советы

  • Не все атрибуты доступны на всех ОС! На Windows нет POSIX-прав, а на Linux нет DOS-атрибутов.
  • Всегда используйте try-catch! Методы могут выбрасывать UnsupportedOperationException или IOException.
  • Права доступа — это не всегда только «rwx»! На Windows модель прав другая, «только для чтения» может задаваться политикой безопасности ОС.
  • Скрытые файлы — понятие относительное. На Unix файл скрыт, если имя начинается с точки (.hidden), на Windows — если установлен атрибут dos:hidden.

Таблица: какие атрибуты где доступны

Атрибут Windows (dos:*) Linux/macOS (posix:*)
Время создания + +
Время последнего изменения + +
Время последнего доступа + +
Скрытый файл + Только имя с точкой
Только для чтения + +
Права доступа (rwx) - +
Владелец, группа - +
Архивный, системный + -

7. Типичные ошибки при работе с атрибутами файлов

Ошибка №1: Попытка прочитать или изменить POSIX-атрибуты на Windows. На Windows вы получите UnsupportedOperationException. Всегда обрабатывайте это исключение, если пишете кроссплатформенный код.

Ошибка №2: Изменение времени модификации файла, который открыт другим процессом. В некоторых системах файл может быть заблокирован, и операция завершится с ошибкой.

Ошибка №3: Ожидание, что операция «скрыть файл» сработает одинаково на всех ОС. На Unix скрыт файл, начинающийся с точки (.gitignore), а на Windows — если выставлен атрибут dos:hidden. Не путайте эти подходы.

Ошибка №4: Пренебрежение проверкой существования файла перед операцией. Если файла нет, получите NoSuchFileException при попытке получить атрибуты или изменить их.

Ошибка №5: Отсутствие проверки прав доступа. Если у пользователя нет прав на изменение атрибутов, операция завершится с ошибкой. Перед изменениями проверяйте Files.isWritable(path).

1
Задача
JAVA 25 SELF, 39 уровень, 4 лекция
Недоступна
Эксперт по безопасности: аудит прав доступа
Эксперт по безопасности: аудит прав доступа
1
Задача
JAVA 25 SELF, 39 уровень, 4 лекция
Недоступна
Смотритель архива: актуализация временной метки
Смотритель архива: актуализация временной метки
1
Опрос
Работа с файловой системой, 39 уровень, 4 лекция
Недоступен
Работа с файловой системой
Работа с файловой системой
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ