1. Wprowadzenie
Wyobraź sobie, że piszesz program, do którego użytkownik wgrywa swoje zdjęcia. Fajnie byłoby przechowywać je nie po prostu "w jednym worku" w jednym folderze, ale tworzyć osobne katalogi — na przykład według daty albo nazwy użytkownika. Albo powiedzmy, że twój program generuje raporty: sensowne jest zapisywanie wyników w dedykowanym katalogu, który też trzeba utworzyć w locie. A usunięcie tymczasowych folderów po pracy to w ogóle obowiązek przyzwoitego kodu (i ulga dla użytkownika od śmieci).
Praca z katalogami to standardowe zadanie w wielu aplikacjach: od backupu po gry, które chcą rozkładać save'y w folderach. Na rozmowach rekrutacyjnych ten temat też często się pojawia, bo ważne jest nie tylko to, że istnieje komenda "utwórz" lub "usuń", ale jak się ona zachowuje w nietypowych sytuacjach.
Katalog (lub folder) to w zasadzie kontener dla innych plików i katalogów w systemie plików. Katalogi tworzą strukturę drzewiastą (filesystem tree): każdy folder ma rodzica, poza najwyższym (root), i może mieć podfoldery — nawet po tysiące.
2. Jak utworzyć folder? Klasa statyczna Directory
Najprostszy sposób na utworzenie folderu to użycie statycznej metody Directory.CreateDirectory. Nie trzeba tworzyć żadnych obiektów, po prostu przekaż ścieżkę:
using System.IO;
// Tworzymy folder "Reports" w bieżącym katalogu
Directory.CreateDirectory("Reports");
Jeśli taki folder już istnieje, metoda nic nie robi i nie rzuca błędu — możesz bezpiecznie wywołać CreateDirectory, nie zastanawiając się, czy folder istnieje.
Spróbujmy podstawić bardziej złożoną ścieżkę, na przykład utworzyć zagnieżdżony folder:
Directory.CreateDirectory(@"Data\Photos\2024\June");
To wywołanie utworzy cały łańcuch katalogów, jeśli jakieś pośrednie foldery nie istniały. To nazywa się tworzeniem rekurencyjnym — Directory.CreateDirectory zadba o wszystko samo.
Ważne! W ścieżkach do katalogów używaj albo podwójnego backslasha (\\) dla Windows, albo slasha (/). Jeszcze lepiej — Path.Combine, o którym mówiliśmy wcześniej.
A co zwraca CreateDirectory?
Metoda zwraca obiekt typu DirectoryInfo. To wygodne, jeśli od razu chcesz pracować z tym katalogiem:
DirectoryInfo reportsDir = Directory.CreateDirectory("Reports");
Console.WriteLine($"Utworzono folder: {reportsDir.FullName}");
Jak sprawdzić, czy folder istnieje?
W każdej sytuacji, gdy chcesz wykonać operację na katalogu, dobrze się upewnić, że on istnieje. Do tego służy metoda statyczna:
bool exists = Directory.Exists("Reports");
if (!exists)
{
Console.WriteLine("Folder nie znaleziony, zaraz utworzymy!");
Directory.CreateDirectory("Reports");
}
Notatka: Nie trzeba robić wstępnego sprawdzenia przed tworzeniem: metoda nic nie zepsuje, jeśli folder istnieje. Ale jeśli chcesz pokazać użytkownikowi ładny komunikat lub prowadzić logikę inaczej, ten sposób się przyda.
3. Tworzenie katalogów: praktyczne przypadki
Połączmy tę wiedzę z naszą przykładową aplikacją. Załóżmy, że prowadzimy ewidencję wpisów użytkowników i chcemy przechowywać dla każdego osobny folder:
// Dodaj System.IO na górę pliku, jeśli go nie ma
using System.IO;
Console.Write("Wpisz nazwę użytkownika: ");
string userName = Console.ReadLine() ?? "Unknown";
// Składamy ścieżkę do folderu użytkownika
string basePath = "UsersData";
string userPath = Path.Combine(basePath, userName);
// Tworzymy folder dla użytkownika (i rodzica, jeśli potrzeba)
Directory.CreateDirectory(userPath);
Console.WriteLine($"Folder dla użytkownika \"{userName}\" gotowy: {Path.GetFullPath(userPath)}");
Przykład powyżej utworzy strukturę plików (jeśli jej nie było):
UsersData/
└── ImieUzytkownika/
Wskazówka: zawsze używaj Path.Combine, jeśli łączysz kawałki ścieżek — wtedy twój kod będzie działał i na Windows, i na Linux/Mac.
4. Jak usunąć folder? Metoda Directory.Delete
Usuwanie folderu jest prawie tak proste jak tworzenie. Ale są niuanse.
Directory.Delete("Reports");
Jeśli folder istnieje i jest pusty — zostanie usunięty bez problemu. Ale jeśli w środku coś jest, zostanie rzucony wyjątek:
System.IO.IOException: "The directory is not empty."
A co jeśli trzeba usunąć folder z zawartością?
Do tego jest przeciążenie metody — z parametrem recursive: true:
Directory.Delete("Reports", recursive: true);
UWAGA: Usuwanie rekurencyjne bezpowrotnie niszczy wszystko wewnątrz folderu. Jeśli wskażesz zły katalog, możesz stracić ważne dane. Zawsze dwa razy sprawdzaj ścieżkę!
Przykład
Dodajmy opcję usunięcia folderu użytkownika (np. jeśli użytkownik skasował konto):
// Pytamy, czy usunąć
Console.Write("Usunąć folder użytkownika? (y/n): ");
string input = Console.ReadLine() ?? "";
if (input.ToLower() == "y")
{
if (Directory.Exists(userPath))
{
// Usuwamy razem ze wszystkimi zawartościami
Directory.Delete(userPath, recursive: true);
Console.WriteLine("Folder użytkownika usunięty!");
}
else
{
Console.WriteLine("Folder już nie istnieje.");
}
}
5. Tabela: Główne metody pracy z folderami
| Operacja | Metoda | Cechy |
|---|---|---|
| Utworzyć folder | |
Rekurencyjnie tworzy wszystkie foldery po ścieżce |
| Sprawdzić istnienie | |
Zwraca true lub false |
| Usunąć pusty folder | |
Rzuca błąd, jeśli folder nie jest pusty |
| Usunąć folder z zawartością | |
Bezpowrotnie kasuje wszystko wewnątrz |
| Pobrać listę plików | |
Zwraca nazwy plików |
| Pobrać listę podfolderów | |
Zwraca nazwy katalogów |
6. Nieoczywiste punkty i typowe błędy
Błąd przy tworzeniu: brak uprawnień lub niepoprawna ścieżka
Jeśli próbujesz utworzyć folder w systemowych katalogach (np. "C:\Windows\System32\SuperApp"), najpewniej dostaniesz wyjątek UnauthorizedAccessException lub IOException.
Praktyczne wskazówki:
Zawsze obsługuj błędy za pomocą try-catch, jeśli pracujesz z zewnętrznymi folderami (np. na pendrive użytkownika lub dysku sieciowym).
Nie ufaj bezkrytycznie wprowadzanym ścieżkom.
try
{
Directory.CreateDirectory(pathFromUser);
}
catch (Exception ex)
{
Console.WriteLine($"Nie udało się utworzyć folderu: {ex.Message}");
}
Usuwanie folderu, jeśli jest używany przez inny proces
Jeśli ktoś (albo twoja własna aplikacja) otworzył plik z folderu i trzyma go otwartego, przy próbie usunięcia folderu dostaniesz IOException — "nie można usunąć, folder jest używany". Najpierw zamknij wszystkie pliki wewnątrz folderu.
Katalog nie jest pusty, a zapomniałeś o recursive: true
Bardzo częsty problem. Jeśli nie przekażesz recursive: true, a folder nie jest pusty — dostaniesz wyjątek.
Używaj ścieżek absolutnych do krytycznych operacji
Praca z ścieżkami względnymi ("Reports") zawsze odnosi się do bieżącego katalogu roboczego aplikacji. Jeśli program jest uruchomiony z innego miejsca, folder zostanie utworzony nie tam, gdzie oczekujesz. Sprawdzaj, skąd uruchamiasz kod, lub od razu podawaj pełną ścieżkę:
string fullPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "MyAppData");
Directory.CreateDirectory(fullPath);
GO TO FULL VERSION