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
Опитування
Робота з файловою системою, рівень 39, лекція 4
Недоступний
Робота з файловою системою
Робота з файловою системою
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ