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
| Властивість | Що повертає? |
|---|---|
|
Дата й час створення файлу/папки |
|
Дата й час останньої зміни |
|
Дата й час останнього доступу |
|
Розмір файлу (у байтах) |
|
Це директорія? |
|
Це звичайний файл? |
|
Це символічне посилання? |
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).
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ