1. Giriş
Stream-lərlə (StreamReader, StreamWriter, FileStream) birbaşa işləmək çox faydalıdır, xüsusən oxuma/yazma prosesini aşağı səviyyədə idarə etmək lazım gəldikdə: məsələn, bloklarla "hissə-hissə" yazmaq və ya böyük faylları hissələrə bölüb emal etmək.
Amma real həyatda çox vaxt sadəcə bunları etmək lazım gəlir: "bu fayl mövcuddurmu?", "faylı bir yerdən başqa yerə kopyalamaq", "faylı silmək", "qovluqdakı bütün .txt fayllarının siyahısını almaq" və s. Bu kimi tapşırıqlar üçün Microsoft iki universal vasitə yaradıb: statik siniflər File və Directory. Statik o deməkdir ki, nümunə yaratmağa ehtiyac yoxdur — birbaşa sinifin adı ilə lazım olan metodu çağırırsınız.
Həyati analogiya
Əgər stream-lər siz və qələm kimi hər hərfi diqqətlə yazmaqdırsa, onda File və Directory sizin çekmecələr olan masanız kimidir: bir çekmeceyi ani açıb (Directory), içindən vərəqi çıxarıb (File.ReadAllText), vərəqi tullaya bilərsiniz (File.Delete) və ya bütün bir çekmecei götürüb otağın digər tərəfinə daşıya bilərsiniz (Directory.Move). Sadə tapşırıqlar — sadə metodlar.
2. File sinifi: nədir və nə üçün lazımdır
File sinifinin fayllarla işləmək üçün çox rahat statik metod dəsti var.
Ən çox istifadə olunan metodlar
| Metod | Təsviri |
|---|---|
|
Yol üzrə faylın olub-olmadığını yoxlayır |
|
Faylı bütünlüklə mətn kimi oxuyur |
|
Fayldakı bütün sətirləri massivə oxuyur |
|
Faylı yenidən yazır, mətni qeyd edir |
|
Mətni faylın sonuna əlavə edir |
|
Faylı kopyalayır |
|
Faylı silir |
|
Faylı köçürür və ya adını dəyişir |
|
Mürəkkəb əməliyyatlar üçün stream açır |
Tez nümunə: faylı yoxlayıb oxuyuruq
string filePath = "data.txt";
if (File.Exists(filePath))
{
string content = File.ReadAllText(filePath);
Console.WriteLine("Faylın məzmunu:");
Console.WriteLine(content);
}
else
{
Console.WriteLine("Fayl tapılmadı!");
}
Görürsünüz? Sadə hal üçün heç bir əl ilə stream idarəsi lazım deyil!
3. Directory sinifi: qovluqları ağrı olmadan idarə et
Əgər File ayrı-ayrı fayllarla bağlıdırsa, onda Directory qovluqlarla (direktoriyalarla) işləyir.
Əsas vəzifələr
| Metod | Təsviri |
|---|---|
|
Qovluğun olub-olmadığını yoxlayır |
|
Qovluğu yaradır (və ya bütün ara qovluqları ilə birlikdə) |
|
Qovluğu silir (subdirektoriyalar daxil ola bilər) |
|
Qovluktakı faylların siyahısını alır |
|
Alt qovluqların siyahısını alır |
|
Qovluğu köçürür və ya adını dəyişir |
|
Tətbiqin cari işçi direktoriyasını almaq |
Nümunə: qovluq yaradıb ora fayl saxlayırıq
string dirPath = "Results";
if (!Directory.Exists(dirPath))
{
Directory.CreateDirectory(dirPath);
Console.WriteLine("Results qovluğu yaradıldı.");
}
string filePath = Path.Combine(dirPath, "summary.txt");
File.WriteAllText(filePath, "Yekun məlumatlar: ...");
Console.WriteLine($"Fayl {filePath} yazıldı.");
4. File və Directory istifadə olunan tipik ssenarilər
Əsas metodlar darıxdırıcı görünə bilər, əgər onları tətbiqdə görməsəniz! Gəlin bu sinifləri real problemlərin həllində necə istifadə etmək olar baxaq və eyni zamanda şərti tətbiqimiz üzərində işləməyə davam edək (tutaq ki, sadə todo-list sistemi yaradırıq və nəticələri fayllarda saxlayırıq).
Veriləri fayla saxlamaq (köhnə faylı əvəz etmək)
// Tapşırıqlar siyahısını fayla saxlayırıq
string[] todos = { "Çörək almaq", "Həkimə zəng etmək", "C# üzrə ev tapşırığını etmək" };
string filePath = "todo.txt";
File.WriteAllLines(filePath, todos);
Console.WriteLine("Tapşırıqlar siyahısı saxlanıldı.");
Fayldan məlumat yükləmək
// Fayl varsa tapşırıqları yükləyirik
if (File.Exists(filePath))
{
string[] loadedTodos = File.ReadAllLines(filePath);
Console.WriteLine("Sizin tapşırıqlar siyahınız:");
foreach (var task in loadedTodos)
{
Console.WriteLine("- " + task);
}
}
else
{
Console.WriteLine("Hələ tapşırıqlar siyahınız yoxdur.");
}
Yeni tapşırıq əlavə etmək (faylı yenidən yazmadan)
string newTask = "İtlə gəzməyə çıxmaq";
File.AppendAllText(filePath, newTask + Environment.NewLine);
Console.WriteLine("Tapşırıq əlavə edildi!");
Faylın kopyalanması və backup yaradılması
string backupPath = "todo_backup.txt";
File.Copy(filePath, backupPath, overwrite: true);
Console.WriteLine("Tapşırıqlar siyahısının ehtiyat nüsxəsi yaradıldı.");
Faylın köçürülməsi (və ya adının dəyişdirilməsi)
string archivePath = "todo_archive.txt";
File.Move(filePath, archivePath);
Console.WriteLine("Tapşırıqlar siyahısı arxivləndi (ad dəyişdirildi).");
Faylın silinməsi
if (File.Exists(archivePath))
{
File.Delete(archivePath);
Console.WriteLine("Arxiv silindi — yer boşaldıldı!");
}
5. Qovluqlarla işləmək: nümunələr
Direktoriyalar iyerarxiyası yaratmaq
string path = Path.Combine("Reports", "2024", "June");
Directory.CreateDirectory(path);
Console.WriteLine($"Qovluq {path} yaradıldı (ara qovluqlar daxil olmaqla).");
Faylların və qovluqların siyahısını almaq
string dirPath = "Reports";
if (Directory.Exists(dirPath))
{
string[] files = Directory.GetFiles(dirPath);
Console.WriteLine("Qovluqdakı fayllar:");
foreach (var file in files)
{
Console.WriteLine(file);
}
string[] subDirs = Directory.GetDirectories(dirPath);
Console.WriteLine("Alt qovluqlar:");
foreach (var dir in subDirs)
{
Console.WriteLine(dir);
}
}
Maskaya görə faylların filtrasiya olunması (yalnız txt)
string[] txtFiles = Directory.GetFiles(dirPath, "*.txt");
Console.WriteLine("Yalnız .txt fayllar:");
foreach (var file in txtFiles)
{
Console.WriteLine(file);
}
Rekursiv gəzinti (bütün alt qovluqlardakı fayllar)
string[] allFiles = Directory.GetFiles(dirPath, "*.*", SearchOption.AllDirectories);
Console.WriteLine("Bütün daxil qovluqlardakı fayllar:");
foreach (var file in allFiles)
{
Console.WriteLine(file);
}
Direktoriyaların köçürülməsi və silinməsi
string from = "OldReports";
string to = "Archive/OldReports";
if (Directory.Exists(from))
{
Directory.Move(from, to);
Console.WriteLine($"Qovluq {from} köçürüldü {to}-ya");
}
if (Directory.Exists(to))
{
Directory.Delete(to, recursive: true); // true: içindəkiləri də sil
Console.WriteLine($"Qovluq {to} silindi (bütün məzmunu ilə).");
}
6. Faydalı nüanslar
Yollarla inteqrasiya: Path sinifi
Fayllar və qovluqlarla işləyərkən tam yolları birləşdirmək, fayl adlarını və uzantılarını ayırmaq, icazəsiz simvolları yoxlamaq lazım gəlir. Bunun üçün köməkçi sinif Path istifadə olunur.
Nümunələr
string folder = "Results";
string filename = "week1.txt";
string fullPath = Path.Combine(folder, filename); // təhlükəsiz birləşdirmə!
Console.WriteLine(fullPath); // "Results/week1.txt" (və ya "\" Windows-da)
- Faylın uzantısını almaq: Path.GetExtension(fullPath)
- Yol olmadan fayl adını almaq: Path.GetFileName(fullPath)
Path.Combine-dən string concatenation əvəzinə istifadə edin — bu kross-platform tətbiqlər üçün daha təhlükəsizdir.
“Hamısını bir dəfəyə” metodlar vs stream variantları
Çoxlu File və Directory metodları (məsələn, File.ReadAllText, File.WriteAllText, Directory.GetFiles) işi "tamamən" yerinə yetirir: faylı bir dəfəyə oxuyur/yazır və ya faylların siyahısını alır. Bu ÇOX rahatdır, amma çox böyük fayllar və ya çox böyük kataloqlar üçün yaddaş çatışmazlığına səbəb ola bilər. Giga-sized fayllarla işləyirsinizsə — stream siniflərinə keçin (StreamReader, StreamWriter, FileStream və s.) və ya faylları hissələr üzrə emal edin.
File/Directory nə vaxt, stream sinifləri nə vaxt istifadə etmək
| Vəziyyət | Nə istifadə etmək |
|---|---|
| Fayl/qovluğun olub-olmadığını yoxlamaq | |
| Küçük faylı tam oxumaq/yazmaq | |
| Fayla mətni əlavə etmək | |
| Direktoriyadakı faylların siyahısını almaq | |
| Faylı kopyalamaq, silmək, köçürmək | |
| Bütöv qovluğu kopyalamaq/silmək | Directory.Delete/Move/Copy (Copy — üçüncü tərəf kitabxana ilə) |
| ÇOX böyük faylları hissə-hissə emal etmək | Stream sinifləri (StreamReader, FileStream) |
Praktiki əhəmiyyət və real tətbiqlər
- Konfiqurasiyaların, ayarların, JSON/XML fayllarının tez yüklənməsi/saxlanması.
- Logging sistemləri (logların diska yazılması).
- Sadə backup və data migration alətləri.
- Multimedia, şəkillər, sənədlər üçün qovluq skaneri.
- İstifadəçi ssenariləri: şablonların yüklənməsi, export/import, hesabatların generasiyası və s.
Praktiki tapşırıqlar və müsahibə sualları da tez-tez məhz bu siniflərin istifadəsini tələb edir: "Direktoriyadakı bütün .txt faylların ümumi ölçüsünü hesablayan funksiya yazın", "Faylların ehtiyat nüsxəsini ayrıca qovluğa köçürün" və s.
Vizual xatırlatma: hansı halda hansı metodu istifadə etmək
graph TD
A[What do you want to do?]
A -->|Check existence| B[File.Exists or Directory.Exists]
A -->|Read/write whole file| C[File.ReadAllText/WriteAllText]
A -->|Append data to file| D[File.AppendAllText]
A -->|Work with directories| E[Directory.CreateDirectory, GetFiles, GetDirectories]
A -->|Copy/delete/move file| F[File.Copy/Delete/Move]
A -->|Copy/delete whole folder| G[Directory.Delete/Move]
7. Xüsusiyyətlər və tipik səhvlər
Existence yoxlaması və "race condition". Fayl/qovluğun mövcudluğunu yoxlasanız belə, həmin yoxlama ilə əməliyyat arasındakı müddətdə başqa bir proses vəziyyəti dəyişə bilər. Buna görə həmişə try-catch istifadə edin, hətta əvvəlcə yoxlamısınızsa da!
İcazələr. Tətbiqin oxuma/yazma/silmə icazəsi yoxdursa, metodlar UnauthorizedAccessException atacaq.
Yol çox uzun ola bilər. Maksimum yol uzunluğu (köhnə Windows-da adətən 260 simvol) məhdudiyyəti var; .NET 9-da bu sərtliyi bir qədər yumşaldıblar, amma diqqətli olun.
Səhvlərin tutulması. File.ReadAllText və ya Directory.GetFiles kimi metodlar səhvi bağışlamırlar: əgər fayl/qovluq yoxdursa — dərhal exception atılır. Buna görə əməliyyatları try-catch-ə alın və ya əvvəlcə mövcudluğu yoxlayın.
GO TO FULL VERSION