1. Faylların kopyalanması
Bu vaxta qədər fayl sistemi ilə əməliyyatlarımız daha çox "bircə vuruş" tipində idi: fayl yaratdın, oxudun, sildin — vəssalam. Amma real həyatda tez-tez ehtiyac olur ki, məzmunu kopyalayasan: sənədlərin backup-ı, şablonların köçürülməsi, məlumatlarla avtomatlaşdırma. Kopyalama uşaq işi kimi görünə bilər (Ctrl+C və Ctrl+V — hamımızın dostu), amma əslində burada kifayət qədər incə məqamlar var.
Bu gün biz faylların və qovluqların kopyalanmasının bütün yollarını nəzərdən keçirəcəyik — ən sadə variantlardan bir az da mürəkkəb olanlara qədər. Həmçinin görəcəyik ki, .NET-in daxili sinifləri bu işi necə həll edir, hansı məhdudiyyətlər var, hansı səhvlər sizi gözləyə bilər və əgər kataloqda iki min qovluq və milyon fayl varsa nə etmək lazımdır.
Class File və metod Copy
Faylı kopyalamanın ən asan yolu statik metoddan istifadə etməkdir: File.Copy. Bu metod mənbə faylın yolunu, yeni faylın yolunu və istəyə bağlı parametrini alır: əgər fayl artıq varsa onu yenidən yazmağa icazə verilsinmi.
using System.IO;
// Sadə fayl kopyalama nümunəsi
File.Copy("source.txt", "destination.txt");
Əgər təyinat faylı artıq varsa, metod istisna atacaq. Yenidən yazmağa açıq olmaq üçün üçüncü parametrdən istifadə edin:
File.Copy("source.txt", "destination.txt", overwrite: true);
Mühüm məqam: Əgər ikinci parametr ("destination.txt") əslində fayla yox, mövcud bir kataloqa göstərirsə, səhv yaranacaq. Metod məhz fayl üçün yol gözləyir!
Yollarla işləmək
Həmişə olduğu kimi, ikiqat və ya əks slash tələsinə düşməmək üçün Path.Combine istifadə etməyi unutmayın:
string sourcePath = Path.Combine("Data", "input.txt");
string destPath = Path.Combine("Backup", "input_backup.txt");
File.Copy(sourcePath, destPath, overwrite: true);
Xətaların idarəsi
Fayl kopyalayanda nə baş verə bilər? Çox şey: fayl başqa proses tərəfindən istifadə edilə bilər, mənbə fayl olmaya bilər, icazəniz çatmaya bilər, təyinat diski dolu ola bilər. İstisnaları idarə edin:
try
{
File.Copy("bigdata.txt", "bigdata_backup.txt", overwrite: false);
Console.WriteLine("Fayl uğurla kopyalandı!");
}
catch (IOException ex)
{
Console.WriteLine($"Input-output xətası: {ex.Message}");
}
catch (UnauthorizedAccessException)
{
Console.WriteLine("Fayla və ya qovluğa giriş icazəsi yoxdur.");
}
catch (Exception ex)
{
Console.WriteLine($"Başqa xəta: {ex.Message}");
}
Class FileInfo və metod CopyTo
Əgər artıq FileInfo obyekti varsa, onun üzərində CopyTo metodunu çağıra bilərsiniz:
var fi = new FileInfo("report.xlsx");
fi.CopyTo("backup_report.xlsx");
Üçüncü arqument (overwrite) CopyTo-da yalnız .NET Core 2.0+ versiyalarında mövcuddur, ona görə köhnə framework üçün yazırsınızsa bu səhv sizi təəccübləndirməsin.
Faylı "heç yerə" kopyalamaq (və ya "tutulmasa oğru deyil")
Kopyalama üçün göstərilən yola diqqətlə yanaşın. Əgər təyinat qovluğu yoxdursa, .NET xəta verəcək. Buna görə faylı kopyalamadan əvvəl qəbul edici direktoriyanın mövcudluğuna əmin olmaq yaxşıdır:
string backupDir = "Backup";
if (!Directory.Exists(backupDir))
{
Directory.CreateDirectory(backupDir);
}
string targetPath = Path.Combine(backupDir, "mydoc.txt");
File.Copy("mydoc.txt", targetPath);
2. Kataloqların kopyalanması: zəif ürək üçün deyil
Budur əsl macəra başlayır! .NET-də bütün işi bir sətrə həll edən "sehrli" Directory.Copy metodu yoxdur (File kimi). Bir az əllə işləmək və bütün faylları və alt qovluqları rekursiv kopyalamaq üçün funksiyanı yazmaq lazımdır.
Niyə Directory.Copy yoxdur?
Kataloqun kopyalanması həmişə sadə olmur. Hər qovluqda fayllar, alt qovluqlar, gizli fayllar, xüsusi icazələr və uzun yollar ola bilər. Ona görə .NET inkişaf etdiriciləri qərar veriblər: "Proqramçılar özləri qərar versinlər nə kopyalamaq lazımdır." Amma biz asan yolu seçmirik — öz funksiyamızı yazacağıq!
Kataloqun rekursiv kopyalanmasına nümunə
Vəzifə: bir qovluğun məzmununu (və onun bütün alt-aləmini) başqa yerə kopyalamaq.
using System;
using System.IO;
void CopyDirectory(string sourceDir, string destDir, bool recursive)
{
// Mənbə qovluğun mövcudluğunu yoxlayırıq
if (!Directory.Exists(sourceDir))
throw new DirectoryNotFoundException($"Mənbə qovluq tapılmadı: {sourceDir}");
// Hələ yoxdursa təyinat qovluğunu yaradırıq
if (!Directory.Exists(destDir))
Directory.CreateDirectory(destDir);
// Bütün faylları kopyalayırıq
foreach (string filePath in Directory.GetFiles(sourceDir))
{
string fileName = Path.GetFileName(filePath);
string destFilePath = Path.Combine(destDir, fileName);
File.Copy(filePath, destFilePath, overwrite: true);
}
// Əgər rekursivdirsə — bütün alt qovluqları kopyalayırıq
if (recursive)
{
foreach (string dirPath in Directory.GetDirectories(sourceDir))
{
string dirName = Path.GetFileName(dirPath);
string destSubDir = Path.Combine(destDir, dirName);
// Rekursiv çağırış!
CopyDirectory(dirPath, destSubDir, recursive);
}
}
}
İstifadəsi:
CopyDirectory("C:\\MyData", "D:\\Backup\\MyData", recursive: true);
Bu funksiya direktoriyaların strukturunu yaradır və bütün faylları, o cümlədən alt qovluqların məzmununu kopyalayır.
Kodu və incə məqamları araşdırmaq
İlk öncə təyinat qovluğunu yaradırıq (əgər yoxdursa) — əks halda faylı ora kopyalamağa çalışanda xəta alarıq. Hər döngüdə Path.GetFileName-dən istifadə edirik ki, yeni yol düz qurulsun və fayl/ qovluq adı itirilməsin.
Qeyd edək ki, əgər kataloqu özünə və ya özünə aid alt qovluğa kopyalasınız, epic rekursiya yaranacaq… və StackOverflowException alacaqsınız. "C:\\Data"-ni "C:\\Data\\Backup"-a kopyalamayın. Kompüter əsəbiləşər!
Yalnız faylları kopyalamaq (alt qovluqlar olmadan)
Bəzən yalnız üst səviyyə faylları kopyalamaq kifayətdir (alt qovluqlara daxil olmadan):
void CopyFilesOnly(string sourceDir, string destDir)
{
if (!Directory.Exists(destDir))
Directory.CreateDirectory(destDir);
foreach (string filePath in Directory.GetFiles(sourceDir))
{
string fileName = Path.GetFileName(filePath);
string destFilePath = Path.Combine(destDir, fileName);
File.Copy(filePath, destFilePath, overwrite: true);
}
}
Nümunə — backup funksionallığını tətbiq edək
Bu funksionallığı kurs boyu inkişaf etdirdiyimiz "HomeApp" tətbiqimizə əlavə edək. İcazə verin indi öz məlumatlarının backup-ını edə bilsin.
using System;
using System.IO;
namespace HomeApp
{
class Program
{
static void CopyDirectory(string sourceDir, string destDir, bool recursive)
{
if (!Directory.Exists(sourceDir))
throw new DirectoryNotFoundException($"Mənbə qovluq tapılmadı: {sourceDir}");
if (!Directory.Exists(destDir))
Directory.CreateDirectory(destDir);
foreach (string filePath in Directory.GetFiles(sourceDir))
{
string fileName = Path.GetFileName(filePath);
string destFilePath = Path.Combine(destDir, fileName);
File.Copy(filePath, destFilePath, overwrite: true);
}
if (recursive)
{
foreach (string dirPath in Directory.GetDirectories(sourceDir))
{
string dirName = Path.GetFileName(dirPath);
string destSubDir = Path.Combine(destDir, dirName);
CopyDirectory(dirPath, destSubDir, recursive);
}
}
}
static void Main(string[] args)
{
Console.WriteLine("İş qovluğunun yolunu daxil edin:");
string source = Console.ReadLine()!;
Console.WriteLine("Backup qovluğu üçün yolu daxil edin:");
string dest = Console.ReadLine()!;
try
{
CopyDirectory(source, dest, recursive: true);
Console.WriteLine("Backup uğurla yaradıldı!");
}
catch (Exception ex)
{
Console.WriteLine("Kopyalama zamanı xəta: " + ex.Message);
}
}
}
}
3. Faydalı incə məqamlar
Müqayisə: fayl vs kataloq — cədvəl
| Fayl | Kataloq | |
|---|---|---|
| Daxili metod | |
- |
| Obyekt yönümlü | |
- |
| Nesting-dən keçmək | Tələb olunmur | Rekursiya tələb olunur |
| Strukturun yaradılması | Avtomatik | Manually yaradılsın |
| Rekursiyanın təhlükəsi | Yox | Bəli — "özünü özünə" kopyalamayın |
Praktik tətbiq və müstəqil iş tapşırıqları
Fayl və qovluq kopyalama tapşırıqları hər yerdə rast gəlinir: backup-dan tutmuş məlumatların migration-na və ya oyun launcher-larında resursların yenilənməsinə qədər. Bu prosedurlar adətən avtomatlaşdırılır ki, əl işi azalsın və "ayyyy, faylı unutdum!" tipli səhvlər olmasın bazar ertəsi səhəri.
Kataloqun kopyalanması o hallarda vacibdir ki, yalnız məzmun yox, həm də struktur — skelet; alt qovluqlar, daxili fayllar, konfiqurasiyalar saxlanılsın.
Kopyalama üçün checklist (məsələ yaşanmaması üçün)
- Mənbənin mövcudluğu
- Təyinat qovluğunun mövcudluğu (lazımdırsa Directory.CreateDirectory ilə yaradın)
- Faylların yenidən yazılma sxemi — overwrite: true lazımdırmı?
- Kataloqu "özünü-özünə" kopyalamırsınız?
- Yolun uzunluğunu aşmırsınız (xüsusən Windows-da)?
- Gizli/sistem faylları nəzərə alınır?
4. Kopyalama zamanı xüsusiyyətlər və tipik səhvlər
İcazə (Permissions)
Kopyalama uğursuz ola bilər əgər proqramınızın mənbə faylları oxumaq ya da təyinat qovluğuna yazmaq icazəsi yoxdursa. Belə halda siz UnauthorizedAccessException-in bir variantını alacaqsınız. Həll yolu — proqramı admin kimi işlətmək (əgər həqiqətən lazımdırsa!) və ya normal qovluqları seçmək.
Faylın tutulması
Əgər fayl başqa proqramda açıqdırsa (məsələn, Excel onu lock edib), File.Copy istisna ata bilər. Bloklayan tətbiqin prosesi kopyalamağa mane olmamasına əmin olun, yoxsa retry məntiqi qurun (try-catch ilə retries).
Faylları yenidən yazmaq
Hansı məntiqi seçmək: təyinat fayllarını overwrite edək yoxsa varsa toxunmayaq? Backup üçün adətən overwrite məntiqli olur (overwrite: true), şablonların duplikasiyası üçün isə yox (overwrite: false).
Gizli və sistem faylların kopyalanması
İstifadə etdiyimiz metodlar (Directory.GetFiles) default olaraq bütün faylları, o cümlədən gizli və sistem faylları qaytarır. Onları keçmək istəyirsinizsə, explicit filter tətbiq edin:
foreach (string filePath in Directory.GetFiles(sourceDir))
{
var attr = File.GetAttributes(filePath);
if ((attr & FileAttributes.Hidden) == FileAttributes.Hidden)
continue; // Gizli faylları keçirik
// Qalan kopyalama kodu
}
Uzun yollarla bağlı səhvlər
Windows uzun müddət yolun uzunluğunu təxminən 260 simvol ilə məhdudlaşdırırdı. Müasir versiyalarda bu məhdudiyyəti qaldırmaq mümkündür, amma əgər köhnə sistemlərlə işləyirsinizsə, uzun yollar problem yarada bilər.
Symbolic link-lər və "junction"lar
Xüsusi ssenarilərdə kataloqlarda symbolic link-lər və ya "junction"lar ola bilər. Normal kopyalama metodları bunları adi qovluq kimi kopyalaya bilər və ya bypass edə bilər. Əksər tədris tapşırıqları üçün bu vacib deyil, amma sistem kataloqları ilə işləyirsinizsə diqqətli olun.
GO TO FULL VERSION