1. Tworzenie plików
Pliki często tworzymy programowo: na potrzeby logów, danych tymczasowych, eksportu raportów, importu danych, zapisu ustawień i wielu innych. W Javie do tego najlepiej używać nowoczesnego API — java.nio.file.
Główne narzędzie: Files.createFile(Path)
Ta metoda tworzy nowy plik pod wskazaną ścieżką. Jeśli plik już istnieje, zostanie zgłoszony wyjątek.
Przykład: tworzymy plik tekstowy w bieżącym katalogu
import java.nio.file.*;
public class CreateFileExample {
public static void main(String[] args) {
Path path = Path.of("hello.txt");
try {
Files.createFile(path);
System.out.println("Plik utworzony: " + path.toAbsolutePath());
} catch (FileAlreadyExistsException e) {
System.out.println("Plik już istnieje: " + path);
} catch (Exception e) {
System.out.println("Błąd podczas tworzenia pliku: " + e.getMessage());
}
}
}
Zwróć uwagę:
Files.createFile zgłasza FileAlreadyExistsException, jeśli plik już istnieje. Dlatego często przed utworzeniem pliku sprawdza się jego istnienie.
Sprawdzanie istnienia pliku
Path path = Path.of("hello.txt");
if (!Files.exists(path)) {
Files.createFile(path);
}
Wskazówka:
Sprawdzenie istnienia pliku — to nie ochrona przed wyścigami między wątkami, ale w większości scenariuszy użytkowych — zupełnie wystarczające podejście.
W skrócie: co dzieje się przy tworzeniu pliku?
- Jeśli plik nie istnieje i ścieżka jest poprawna — tworzony jest nowy pusty plik.
- Jeśli plik już istnieje — zgłaszany jest wyjątek.
- Jeśli ścieżka jest niepoprawna, brak uprawnień albo katalog nie istnieje — zostanie zgłoszony inny wyjątek (IOException, NoSuchFileException itp.).
2. Tworzenie katalogów
Różnica między Files.createDirectory i Files.createDirectories
- Files.createDirectory(Path) — tworzy tylko jeden katalog. Jeśli katalog nadrzędny nie istnieje — wystąpi błąd.
- Files.createDirectories(Path) — tworzy cały łańcuch brakujących katalogów (jak czarodziej budujący schody tuż pod stopami).
Przykład: tworzymy pojedynczy katalog
Path dir = Path.of("data");
try {
Files.createDirectory(dir);
System.out.println("Katalog utworzony: " + dir.toAbsolutePath());
} catch (FileAlreadyExistsException e) {
System.out.println("Katalog już istnieje: " + dir);
} catch (Exception e) {
System.out.println("Błąd podczas tworzenia katalogu: " + e.getMessage());
}
Przykład: tworzymy strukturę zagnieżdżonych katalogów
Path nested = Path.of("data/reports/2024");
try {
Files.createDirectories(nested);
System.out.println("Struktura katalogów utworzona: " + nested.toAbsolutePath());
} catch (Exception e) {
System.out.println("Błąd podczas tworzenia struktury: " + e.getMessage());
}
Zwróć uwagę: jeśli któryś z katalogów już istnieje, createDirectories się tym nie przejmuje — po prostu tworzy brakujące. Jeśli użyjesz createDirectory dla katalogu zagnieżdżonego, a nadrzędnego jeszcze nie ma — pojawi się błąd.
Tabela: porównanie metod tworzenia katalogów
| Metoda | Tworzy tylko jeden katalog | Tworzy zagnieżdżone katalogi | Nie zgłasza błędu, jeśli część już istnieje |
|---|---|---|---|
|
✔ | ✗ | ✗ |
|
✔ | ✔ | ✔ |
3. Usuwanie plików
Usuwanie plików to prawie jak wyrzucanie śmieci — najważniejsze to nie wyrzucić czegoś potrzebnego! W Javie są do tego dwie podstawowe metody:
- Files.delete(Path) — usuwa plik lub pusty katalog. Jeśli pliku nie ma — zostanie zgłoszony wyjątek.
- Files.deleteIfExists(Path) — usuwa plik, ale jeśli go nie było — po prostu nic nie robi.
Przykład: usuwamy plik tymczasowy
Path tempFile = Path.of("temp.txt");
try {
Files.delete(tempFile);
System.out.println("Plik usunięty: " + tempFile);
} catch (NoSuchFileException e) {
System.out.println("Plik nie znaleziony: " + tempFile);
} catch (DirectoryNotEmptyException e) {
System.out.println("Katalog nie jest pusty: " + tempFile);
} catch (Exception e) {
System.out.println("Błąd podczas usuwania: " + e.getMessage());
}
Bardziej bezpieczne podejście
boolean deleted = Files.deleteIfExists(tempFile);
if (deleted) {
System.out.println("Plik został usunięty.");
} else {
System.out.println("Pliku nie znaleziono — nie ma czego usuwać.");
}
Ważne!
- Jeśli plik jest otwarty w innym programie — może zostać zgłoszony wyjątek (np. w systemie Windows).
- Jeśli spróbujesz usunąć katalog, który nie jest pusty — pojawi się błąd DirectoryNotEmptyException.
4. Usuwanie katalogów
Katalogi w Javie usuwamy podobnie jak pliki. Jest jednak pewien niuans: standardowe metody usuwają tylko puste katalogi.
Przykład: usuwamy pusty katalog
Path emptyDir = Path.of("empty_folder");
try {
Files.delete(emptyDir);
System.out.println("Katalog usunięty: " + emptyDir);
} catch (DirectoryNotEmptyException e) {
System.out.println("Katalog nie jest pusty: " + emptyDir);
} catch (NoSuchFileException e) {
System.out.println("Katalog nie znaleziony: " + emptyDir);
} catch (Exception e) {
System.out.println("Błąd podczas usuwania katalogu: " + e.getMessage());
}
Co zrobić z niepustymi katalogami?
Aby usunąć niepuste katalogi, trzeba rekurencyjnie usunąć wszystkie zagnieżdżone pliki i podkatalogi. To temat na osobną lekcję (i osobną przygodę), ale jeśli już nie możesz się doczekać, oto kod — przeanalizuj go i spróbuj odtworzyć:
import java.nio.file.*;
import java.io.IOException;
public class DeleteDirectoryRecursively {
public static void deleteRecursively(Path path) throws IOException {
if (Files.isDirectory(path)) {
try (var entries = Files.list(path)) {
for (Path entry : entries.toList()) {
deleteRecursively(entry);
}
}
}
Files.delete(path);
}
}
Uwaga:
Ten kod usunie wszystko, co znajduje się w katalogu! Używaj go ostrożnie.
5. Praktyczne wskazówki
Sprawdzanie istnienia przed usunięciem
if (Files.exists(path)) {
Files.delete(path);
} else {
System.out.println("Plik/katalog nie istnieje.");
}
Ale jeśli używasz deleteIfExists, nie jest to konieczne.
Obsługa wyjątków
Podczas pracy z plikami często napotykamy niespodzianki. Java zgłasza w takich sytuacjach różne wyjątki:
- NoSuchFileException — plik lub katalog nie został znaleziony. Na przykład próbujesz otworzyć coś, co już zostało usunięte.
- DirectoryNotEmptyException — próbujesz usunąć katalog, ale w środku coś jeszcze się znajduje.
- IOException — ogólny sygnał: coś poszło nie tak. Przyczyna może być różna — brak uprawnień, plik zajęty przez inny program, niepoprawna ścieżka.
Schemat wizualny: podstawowe metody
+-------------------+ +--------------------+
| Files.createFile | ----> | Nowy plik |
+-------------------+ +--------------------+
+---------------------+ +--------------------+
| Files.createDirectory|----> | Nowy katalog |
+---------------------+ +--------------------+
+-------------------+ +--------------------+
| Files.delete | ----> | Plik/katalog usunięty |
+-------------------+ +--------------------+
(ale tylko jeśli katalog jest pusty!)
6. Typowe błędy przy tworzeniu i usuwaniu plików i katalogów
Błąd nr 1: Próbujemy utworzyć plik/katalog, który już istnieje. Metody Files.createFile i Files.createDirectory zgłaszają wyjątek, jeśli obiekt już istnieje. Rozwiązanie — sprawdzać istnienie wcześniej lub łapać wyjątek.
Błąd nr 2: Próbujemy utworzyć zagnieżdżony katalog przez createDirectory, a katalog nadrzędny jeszcze nie istnieje. W takim przypadku wystąpi błąd NoSuchFileException. Użyj createDirectories do utworzenia łańcucha katalogów.
Błąd nr 3: Próbujemy usunąć niepusty katalog metodą Files.delete. Otrzymasz DirectoryNotEmptyException. Do usuwania niepustych katalogów potrzebna jest rekurencja.
Błąd nr 4: Brak uprawnień do tworzenia/usuwania w wskazanym katalogu. Zostanie zgłoszony AccessDeniedException lub IOException. Uruchom program z odpowiednimi uprawnieniami albo użyj dostępnych katalogów.
Błąd nr 5: Plik jest zajęty przez inny proces. W systemie Windows (i czasem w innych OS) nie można usunąć pliku, jeśli jest otwarty w innym programie. Otrzymasz IOException. Zamknij wszystkie aplikacje używające pliku przed usunięciem.
Błąd nr 6: Używanie ścieżek względnych bez świadomości „gdzie się znajdujesz”. Plik tworzy się nie tam, gdzie się spodziewasz. Dla pewności używaj toAbsolutePath() i wypisuj ścieżkę na ekran.
GO TO FULL VERSION