1. Odczyt podstawowych atrybutów: BasicFileAttributes
Kiedy mówimy o pliku lub folderze, mamy na myśli nie tylko jego nazwę czy rozmiar. Każdy plik ma „paszport” – zestaw atrybutów, który zawiera:
- Czas utworzenia
- Czas ostatniej modyfikacji
- Czas ostatniego dostępu
- Rozmiar
- Uprawnienia (kto może czytać, pisać, wykonywać)
- Informacje o właścicielu (w systemach Unix)
- Flagi „ukryty”, „tylko do odczytu” itp.
W Javie do pracy z tymi atrybutami jest wygodne i potężne API w pakiecie java.nio.file.attribute. Nie trzeba pisać kodu zależnego od platformy – wszystko, co potrzebne, jest w standardowej bibliotece.
Na początek – importujemy potrzebne klasy:
import java.nio.file.*;
import java.nio.file.attribute.*;
import java.io.IOException;
Jak pobrać podstawowe atrybuty pliku?
Używamy metody Files.readAttributes:
Path path = Paths.get("example.txt");
try {
BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
System.out.println("Utworzono: " + attrs.creationTime());
System.out.println("Ostatnia modyfikacja: " + attrs.lastModifiedTime());
System.out.println("Ostatni dostęp: " + attrs.lastAccessTime());
System.out.println("Rozmiar: " + attrs.size());
System.out.println("Czy to katalog? " + attrs.isDirectory());
System.out.println("Czy to plik? " + attrs.isRegularFile());
System.out.println("Czy to dowiązanie symboliczne? " + attrs.isSymbolicLink());
} catch (IOException e) {
System.out.println("Błąd podczas odczytu atrybutów: " + e.getMessage());
}
Wyobraź sobie, że jesteś inspektorem i przyszedłeś sprawdzić mieszkanie. Nie tylko patrzysz, czy są drzwi (czy plik istnieje), ale też pytasz lokatorów: „Kiedy zbudowano dom? Kiedy ostatnio był remont? Kto jest właścicielem?”.
Krótko o właściwościach BasicFileAttributes
| Właściwość | Co zwraca? |
|---|---|
|
Data i czas utworzenia pliku/folderu |
|
Data i czas ostatniej modyfikacji |
|
Data i czas ostatniego dostępu |
|
Rozmiar pliku (w bajtach) |
|
Czy to katalog? |
|
Czy to zwykły plik? |
|
Czy to dowiązanie symboliczne? |
2. Rozszerzone atrybuty: POSIX i DOS
Atrybuty POSIX (Linux, macOS i inne systemy uniksowe)
Jeśli pracujesz w systemie Unix, możesz uzyskać rozszerzone informacje: uprawnienia, właściciel, grupa.
try {
PosixFileAttributes posixAttrs = Files.readAttributes(path, PosixFileAttributes.class);
System.out.println("Właściciel: " + posixAttrs.owner().getName());
System.out.println("Grupa: " + posixAttrs.group().getName());
System.out.println("Uprawnienia: " + PosixFilePermissions.toString(posixAttrs.permissions()));
} catch (UnsupportedOperationException e) {
System.out.println("Atrybuty POSIX nie są obsługiwane w tym systemie operacyjnym.");
} catch (IOException e) {
System.out.println("Błąd podczas odczytu atrybutów POSIX: " + e.getMessage());
}
Uwaga: W systemie Windows ten kod zgłosi UnsupportedOperationException – to normalne.
Atrybuty DOS (Windows)
W systemie Windows można pracować z flagami „tylko do odczytu”, „ukryty”, „archiwalny”, „systemowy”:
try {
DosFileAttributes dosAttrs = Files.readAttributes(path, DosFileAttributes.class);
System.out.println("Ukryty: " + dosAttrs.isHidden());
System.out.println("Tylko do odczytu: " + dosAttrs.isReadOnly());
System.out.println("Systemowy: " + dosAttrs.isSystem());
System.out.println("Archiwalny: " + dosAttrs.isArchive());
} catch (UnsupportedOperationException e) {
System.out.println("Atrybuty DOS nie są obsługiwane w tym systemie operacyjnym.");
} catch (IOException e) {
System.out.println("Błąd podczas odczytu atrybutów DOS: " + e.getMessage());
}
3. Modyfikowanie atrybutów plików
Czytanie cudzych „paszportów” to jedno, a zmiana daty urodzenia lub nazwiska – to co innego! W Javie możemy zmieniać atrybuty plików (oczywiście mając odpowiednie uprawnienia).
Zmiana czasu ostatniej modyfikacji
import java.nio.file.attribute.FileTime;
Path file = Paths.get("example.txt");
try {
FileTime newTime = FileTime.fromMillis(System.currentTimeMillis() - 24 * 60 * 60 * 1000); // minus 1 dzień
Files.setLastModifiedTime(file, newTime);
System.out.println("Czas ostatniej modyfikacji został zmieniony!");
} catch (IOException e) {
System.out.println("Błąd podczas zmiany czasu: " + e.getMessage());
}
Zmiana uprawnień (POSIX)
Tylko dla systemów Unix! Na przykład uczynić plik wykonywalnym dla wszystkich:
try {
Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rwxr-xr-x");
Files.setPosixFilePermissions(file, perms);
System.out.println("Uprawnienia zostały zmienione!");
} catch (UnsupportedOperationException e) {
System.out.println("Uprawnienia POSIX nie są obsługiwane w tym systemie operacyjnym.");
} catch (IOException e) {
System.out.println("Błąd podczas zmiany uprawnień: " + e.getMessage());
}
Objaśnienie ciągu "rwxr-xr-x":
- r — read (odczyt)
- w — write (zapis)
- x — execute (wykonywanie)
- Pierwszy blok z 3 znaków – właściciel, drugi – grupa, trzeci – pozostali.
Zmiana statusu ukryty/tylko do odczytu (atrybuty DOS, Windows)
Ustawić plik jako ukryty:
try {
Files.setAttribute(file, "dos:hidden", true);
System.out.println("Plik stał się ukryty (Windows)!");
} catch (UnsupportedOperationException e) {
System.out.println("Atrybuty DOS nie są obsługiwane w tym systemie operacyjnym.");
} catch (IOException e) {
System.out.println("Błąd podczas zmiany atrybutu: " + e.getMessage());
}
Ustawić plik jako „tylko do odczytu”:
try {
Files.setAttribute(file, "dos:readonly", true);
System.out.println("Plik jest teraz tylko do odczytu (Windows)!");
} catch (UnsupportedOperationException e) {
System.out.println("Atrybuty DOS nie są obsługiwane w tym systemie operacyjnym.");
} catch (IOException e) {
System.out.println("Błąd podczas zmiany atrybutu: " + e.getMessage());
}
4. Sprawdzanie praw dostępu
Czasem ważne jest szybkie sprawdzenie, czy plik można otworzyć do odczytu, zapisu lub wykonania:
Path file = Paths.get("example.txt");
System.out.println("Odczyt dozwolony: " + Files.isReadable(file));
System.out.println("Zapis dozwolony: " + Files.isWritable(file));
System.out.println("Wykonywanie dozwolone: " + Files.isExecutable(file));
To działa tak samo na wszystkich platformach, choć rzeczywiste zachowanie zależy od systemu operacyjnego i ustawień zabezpieczeń.
5. Praktyka: wyświetlanie szczegółowych informacji o pliku
Napiszmy mini-program, który na podstawie ścieżki do pliku pokaże maksimum informacji i spróbuje zmienić niektóre atrybuty.
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("Nie znaleziono pliku!");
return;
}
// Podstawowe atrybuty
BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
System.out.println("Nazwa: " + path.getFileName());
System.out.println("Ścieżka: " + path.toAbsolutePath());
System.out.println("Rozmiar: " + attrs.size() + " bajtów");
System.out.println("Utworzono: " + attrs.creationTime());
System.out.println("Ostatnia modyfikacja: " + attrs.lastModifiedTime());
System.out.println("Ostatni dostęp: " + attrs.lastAccessTime());
System.out.println("Czy to katalog? " + attrs.isDirectory());
System.out.println("Czy to zwykły plik? " + attrs.isRegularFile());
// Sprawdzanie praw dostępu
System.out.println("Odczyt dozwolony: " + Files.isReadable(path));
System.out.println("Zapis dozwolony: " + Files.isWritable(path));
System.out.println("Wykonywanie dozwolone: " + Files.isExecutable(path));
// Spróbujmy zmienić czas modyfikacji
FileTime now = FileTime.fromMillis(System.currentTimeMillis());
Files.setLastModifiedTime(path, now);
System.out.println("Czas ostatniej modyfikacji zaktualizowany!");
// Spróbujmy ustawić plik jako ukryty (jeśli obsługiwane)
try {
Files.setAttribute(path, "dos:hidden", true);
System.out.println("Plik stał się ukryty (jeśli jest obsługiwane przez system).");
} catch (UnsupportedOperationException e) {
System.out.println("Ukryte pliki nie są obsługiwane w tym systemie.");
}
// Spróbujmy wyświetlić uprawnienia POSIX (jeśli obsługiwane)
try {
PosixFileAttributes posixAttrs = Files.readAttributes(path, PosixFileAttributes.class);
System.out.println("Właściciel: " + posixAttrs.owner().getName());
System.out.println("Uprawnienia: " + PosixFilePermissions.toString(posixAttrs.permissions()));
} catch (UnsupportedOperationException e) {
System.out.println("Atrybuty POSIX nie są obsługiwane w tym systemie.");
}
}
}
6. Przydatne uwagi
Różnice między platformami i wskazówki
- Nie wszystkie atrybuty są dostępne na wszystkich systemach! W Windows nie ma uprawnień POSIX, a w Linuksie nie ma atrybutów DOS.
- Zawsze używaj try-catch! Metody mogą zgłaszać UnsupportedOperationException lub IOException.
- Uprawnienia to nie zawsze tylko „rwx”! W Windows model uprawnień jest inny; „tylko do odczytu” może wynikać z polityki zabezpieczeń systemu.
- Ukryte pliki to pojęcie względne. W Unixie plik jest ukryty, jeśli jego nazwa zaczyna się kropką (.hidden), w Windows – jeśli ustawiono atrybut dos:hidden.
Tabela: gdzie dostępne są które atrybuty
| Atrybut | Windows (dos:*) | Linux/macOS (posix:*) |
|---|---|---|
| Czas utworzenia | + | + |
| Czas ostatniej modyfikacji | + | + |
| Czas ostatniego dostępu | + | + |
| Ukryty plik | + | Tylko nazwa z kropką |
| Tylko do odczytu | + | + |
| Uprawnienia (rwx) | - | + |
| Właściciel, grupa | - | + |
| Archiwalny, systemowy | + | - |
7. Typowe błędy podczas pracy z atrybutami plików
Błąd nr 1: Próba odczytu lub zmiany atrybutów POSIX w Windows. W Windows otrzymasz UnsupportedOperationException. Zawsze obsługuj ten wyjątek, jeśli piszesz kod wieloplatformowy.
Błąd nr 2: Zmiana czasu modyfikacji pliku, który jest otwarty przez inny proces. W niektórych systemach plik może być zablokowany i operacja zakończy się błędem.
Błąd nr 3: Oczekiwanie, że operacja „ukryj plik” zadziała jednakowo na wszystkich systemach. W Unixie ukryty jest plik rozpoczynający się kropką (.gitignore), a w Windows – gdy ustawiono atrybut dos:hidden. Nie myl tych podejść.
Błąd nr 4: Zaniedbanie sprawdzenia istnienia pliku przed operacją. Jeśli pliku nie ma, otrzymasz NoSuchFileException przy próbie pobrania atrybutów lub ich zmiany.
Błąd nr 5: Brak sprawdzenia uprawnień. Jeśli użytkownik nie ma praw do zmiany atrybutów, operacja zakończy się błędem. Przed zmianami sprawdzaj Files.isWritable(path).
GO TO FULL VERSION