1. Wprowadzenie
Plik — to po prostu blok danych, który fizycznie siedzi na jakimś nośniku: dysku twardym, SSD, pendrive, a nawet na dyskietce (pozdrowienia dla twojego dziadka!). Dla użytkownika plik to coś, co można otworzyć, przeczytać, zmienić i zapisać.
W programowaniu plik to sekwencja bajtów z jakąś nazwą i lokalizacją, a dla ciebie, jako programisty — to obiekt, który ma nazwę, ścieżkę (jak adres), rozmiar, datę utworzenia itd. Najważniejsze: plik to persistentne (trwałe) przechowywanie danych. Wszystko, co dzieje się w pamięci po starcie programu, zwykle znika po jego zakończeniu, a plik — zostaje.
Czym jest system plików?
System plików — to sposób przechowywania i organizowania plików na dysku. Odpowiada na pytania: gdzie i jak szukać plik, kto ma do niego dostęp, jak dokładnie zorganizowane są foldery (katalogi), jak znaleźć nazwę pliku i jego zawartość.
Wyobraź sobie wielką szafę z mnóstwem szuflad. W każdej szufladzie mogą być teczki, a w każdej teczce — dokumenty (pliki). Żeby znaleźć swoje notatki z C#, musisz otworzyć szafę, znaleźć odpowiednią szufladę, wyciągnąć teczkę i w niej — poszukać kartki. Tak właśnie system plików organizuje informacje.
Popularne systemy plików
- NTFS — "rodzimy" system plików Windowsa.
- FAT32, exFAT — do pendrive'ów, kart SD, zewnętrznych dysków.
- EXT4 — popularny w Linuxie.
- APFS, HFS+ — macOS.
Dla programisty C# to zwykle nie ma znaczenia: .NET ukrywa szczegóły implementacji, a ty pracujesz z abstrakcją "plik/folder". Ale czasem warto coś wiedzieć. Na przykład w NTFS możesz mieć spacje i wiele znaków specjalnych w nazwie pliku, a w FAT32 — już nie.
2. Jak zorganizowane są katalogi (foldery)
Katalog (albo folder) — to specjalny typ pliku, który zawiera listy innych plików i/lub katalogów. Drzewo katalogów (hierarchia plików) — to ta znana ścieżka od korzenia do pliku: na przykład, C:\Users\Jan\Documents\MojPlik.txt.
- Korzeń — to sam początek dysku (C:\).
- W środku — foldery (podfoldery), w których leżą pliki lub kolejne foldery.
Oto prosta wizualizacja:
C:\
└── Users\
└── Jan\
├── Documents\
│ └── MojPlik.txt
└── Pictures\
└── Kot.jpg
3. Czym jest ścieżka do pliku (file path)?
Ścieżka do pliku — to "adres" pliku w drzewie katalogów. Dzięki niej możesz jednoznacznie znaleźć potrzebny plik lub folder.
Ścieżka absolutna i względna
- Ścieżka absolutna: zaczyna się od korzenia systemu plików.
Windows: C:\Users\Jan\Documents\MojPlik.txt
Linux/macOS: /home/jan/Documents/MojPlik.txt - Ścieżka względna: zaczyna się od bieżącej lokalizacji (bieżącego katalogu).
Na przykład, jeśli twój program wystartował z folderu C:\Users\Jan, to ścieżka względna Documents\MojPlik.txt prowadzi do tego samego pliku.
Bieżący katalog — to specjalne pojęcie: to "punkt odniesienia" dla wszystkich ścieżek względnych. Po uruchomieniu programu to zwykle folder, gdzie leży plik .exe, albo ten, w którym otworzyłeś konsolę.
Schemat: Ścieżka absolutna i względna
Ścieżka absolutna Ścieżka względna
C:\Projects\MojaAplikacja\logs\output.txt logs\output.txt
└─ Korzeń dysku (C:) └─ Względem uruchomionej MojaAplikacja
Separatory w ścieżkach: \ i /
W Windows używa się backslasha (\), a w Linux/macOS — zwykle slasha (/).
Nowoczesny .NET obsługuje oba warianty, ale nie mieszaj ich w jednym projekcie. Do budowania ścieżek zawsze używaj specjalnego API (application programming interface), a nie sklejaj stringów ręcznie.
4. Jak program widzi plik
W .NET masz szeroki zestaw narzędzi do pracy z plikami. Najważniejsze z nich:
- System.IO.File: statyczne metody do szybkiego czytania, zapisu, usuwania, sprawdzania istnienia plików itd.
- System.IO.Directory: podobne metody do pracy z folderami.
- System.IO.FileInfo i System.IO.DirectoryInfo: obiektowe opakowania z dostępem do metadanych pliku/folderu.
- System.IO.Path: klasa-helper do pracy ze ścieżkami (łączenie ścieżek, wyciąganie rozszerzenia, nazwy itd.).
Trochę przykładów
Sprawdzanie istnienia pliku
using System.IO;
if (File.Exists("dane.txt"))
{
Console.WriteLine("Plik znaleziony!");
}
else
{
Console.WriteLine("Plik nie znaleziony!");
}
Pobieranie rozmiaru pliku
var info = new FileInfo("dane.txt");
Console.WriteLine($"Rozmiar pliku: {info.Length} bajtów");
Działanie wszystkich przykładów omówimy na kolejnych wykładach. Teraz — po prostu patrz i podziwiaj :).
5. Przydatne niuanse
Metadane pliku: nazwa, rozszerzenie, rozmiar, daty itd.
Gdy pracujesz z plikiem, interesuje cię nie tylko jego zawartość — jest jeszcze "paszport pliku":
- Nazwa — to, jak plik nazywa się dla człowieka.
- Rozszerzenie — .txt, .jpg, .exe, .cs itd.: czasem pomaga zrozumieć, co jest w środku.
- Rozmiar — liczba bajtów.
- Czas utworzenia/modyfikacji — możesz sprawdzić, kiedy plik powstał lub był ostatnio zmieniany.
- Atrybuty — na przykład: plik tylko do odczytu, ukryty, systemowy.
W .NET do pracy z tym wygodne są klasy FileInfo, DirectoryInfo (będzie na jednym z kolejnych wykładów).
Rozszerzenia plików i formaty
Rozszerzenie pliku — to tylko część nazwy po kropce. Na przykład, w dokument.txt rozszerzenie to txt. System operacyjny używa rozszerzenia, żeby wiedzieć, czym "otworzyć" plik (np. .jpg — program do obrazków, .xls — Excel itd).
Ale dla programisty rozszerzenie — to tylko podpowiedź. Prawdziwy format pliku określa tylko jego zawartość. Możesz np. otworzyć plik MojKot.jpg jako tekstowy — i zobaczysz masę "krzaków" (jakieś dziwne znaki, ale na pewno nie obrazek). Więc pamiętaj: rozszerzenie — to nie gwarancja, tylko umowa.
Jak działa czytanie i zapis pliku: podstawy
Plik — to sekwencja bajtów. Praca z plikiem w C# zwykle oznacza:
- Otwieranie pliku do czytania lub zapisu (albo obu naraz).
- Czytanie danych do pamięci.
- Zapis nowych danych na dysk.
- Zamykanie pliku — bardzo ważne, bo inaczej blokujesz zasób systemowy (i ktoś nie będzie mógł usunąć pliku, dopóki go trzymasz otwartego).
Nowoczesne API w .NET dbają o ciebie: np. klasa File potrafi otworzyć plik, przeczytać i od razu zamknąć. Ale przy pracy ze strumieniami (Stream) i dużymi plikami trzeba już uważać (o tym pogadamy na kolejnych wykładach).
Co warto wiedzieć o cross-platformowości
Prawie cały współczesny C# działa pod Windows, Linux i macOS praktycznie tak samo. Ale są niuanse. Najczęstszy — to różnica w separatorach (\ vs /), a także ograniczenia długości nazwy pliku i zakazane znaki.
Dlatego API typu Path.Combine i metody z System.IO.Path — to twoi najlepsi kumple. One "skleją" ścieżkę poprawnie na każdym OS. Nigdy nie pisz tak:
var filePath = "C:\\Users\\Jan\\dane.txt"; // Tylko dla Windows!
Lepiej:
var filePath = Path.Combine("Users", "Jan", "dane.txt");
Jak sprawdzić bieżący katalog roboczy?
Czasem ważne jest, gdzie dokładnie zapiszą się twoje pliki. Do tego jest specjalna klasa:
string currentDir = Environment.CurrentDirectory;
Console.WriteLine($"Bieżący katalog: {currentDir}");
A tak w ogóle, jeśli dasz użytkownikowi możliwość wyboru ścieżki, użyj dialogów wyboru pliku/folderu albo argumentów linii poleceń.
GO TO FULL VERSION