CodeGym /Kurslar /C# SELF /Fayllar və kataloqlar haqqında məlumatın əldə edilməsi

Fayllar və kataloqlar haqqında məlumatın əldə edilməsi

C# SELF
Səviyyə , Dərs
Mövcuddur

1. Giriş

Windows-da (və yalnız Windows deyil) hər bir fayl və kataloq bir sıra xassələrə (metadata) malikdir: tam yol, ad, extension, ölçü, yaradılma/dəyişmə/əldə etmə tarixləri, atributlar və s. Təsəvvür edin: fayl yalnız baytlardan ibarət deyil, həm də onu oxumaq üçün FileInfoDirectoryInfo ilə əldə edə biləcəyiniz bir formadır.

Xassə Təsvir Nümunə
Tam yol Fayl/qovluğun tam adı
C:\data\myfile.txt
Ad Yoldan ayrı ad
myfile.txt
Extension .txt, .csv, .jpg və s.
.txt
Ölçü (Bytes) Faylın baytla ölçüsü
4096
Yaradılma tarixi Fayl/qovluq nə vaxt yaradılıb
2024-04-16 19:30:10
Dəyişmə tarixi Məzmun son dəfə nə vaxt dəyişib
2024-05-01 18:14:02
Atributlar Məsələn, yalnız oxu, gizli və s.
ReadOnly, Hidden
Valideyn qovluq Fayl/kataloqun yerləşdiyi qovluq
C:\data

2. Fayl xassələri ilə dərin işləmək

Vaxt möhürlərinin detallı analizi

CreationTime, LastWriteTime, LastAccessTime xassələri DateTime qaytarır və onların davranışı fayl sistemi və faylla əməliyyatlardan asılıdır.


var fileInfo = new FileInfo("document.txt");

if (fileInfo.Exists)
{
    Console.WriteLine($"Yaradılıb: {fileInfo.CreationTime:yyyy-MM-dd HH:mm:ss}");
    Console.WriteLine($"Dəyişdirilib: {fileInfo.LastWriteTime:yyyy-MM-dd HH:mm:ss}");
    Console.WriteLine($"Açılıb: {fileInfo.LastAccessTime:yyyy-MM-dd HH:mm:ss}");
    
    // Yaradılma ilə son dəyişmə arasındakı fərq
    var age = fileInfo.LastWriteTime - fileInfo.CreationTime;
    Console.WriteLine($"Fayl dəyişdirilmişdir: {age.TotalDays:F1} gün ərzində");
}

Maraqlıdır ki, fayl köçürüldükdə yaradılma tarixi adətən cari tarixə yenilənir, amma dəyişmə tarixi orijinaldan qala bilər. Bu backup və fəaliyyət analizində vacibdir.

Fayl adları və extension ilə işləmək

FullName, NameExtension xassələri sadə görünür, amma nüanslar olur: extension olmaması, tərkib extension-lar (məsələn .tar.gz) və nöqtə ilə başlayan gizli fayllar.


var files = new[]
{
    new FileInfo("document.txt"),
    new FileInfo("archive.tar.gz"),
    new FileInfo("README"),
    new FileInfo(".gitignore")
};

foreach (var file in files)
{
    Console.WriteLine($"Tam ad: {file.FullName}");
    Console.WriteLine($"Ad: {file.Name}");
    Console.WriteLine($"Extension: '{file.Extension}'");
    
    // Extension-suz ad
    string nameWithoutExtension = Path.GetFileNameWithoutExtension(file.Name);
    Console.WriteLine($"Extension-suz ad: {nameWithoutExtension}");
    Console.WriteLine("---");
}

Fayl ölçüləri və formatlaşdırma

Length xassəsi ölçünü baytlarda qaytarır; istifadəçi üçün KB/MB/GB görmək daha rahatdır. Yardımçı funksiya:


static string FormatFileSize(long bytes)
{
    string[] suffixes = { "Б", "КБ", "МБ", "ГБ", "ТБ" };
    int counter = 0;
    decimal number = bytes;
    
    while (Math.Round(number / 1024) >= 1)
    {
        number /= 1024;
        counter++;
    }
    
    return $"{number:N1} {suffixes[counter]}";
}

// İstifadə
var file = new FileInfo("bigfile.zip");
if (file.Exists)
{
    Console.WriteLine($"Faylın ölçüsü: {FormatFileSize(file.Length)}");
}

3. Fayl atributları ilə geniş iş

Atributlar bit-flag-lardan ibarət FileAttributes enumeration-u ilə təqdim olunur, yəni faylda eyni anda bir neçə atribut ola bilər. HasFlag vasitəsilə yoxlamaq rahatdır.


var fileInfo = new FileInfo("important.txt");

Console.WriteLine($"Fayl atributları: {fileInfo.Attributes}");

// Müəyyən atributları yoxlayaq
if (fileInfo.Attributes.HasFlag(FileAttributes.Hidden))
{
    Console.WriteLine("Fayl gizlidir!");
}

if (fileInfo.Attributes.HasFlag(FileAttributes.ReadOnly))
{
    Console.WriteLine("Fayl yazılmaya qarşı qorunur!");
}

if (fileInfo.Attributes.HasFlag(FileAttributes.System))
{
    Console.WriteLine("Bu sistem faylıdır!");
}

Atributları proqram vasitəsilə dəyişə bilərsiniz:


// Faylı gizli et
fileInfo.Attributes |= FileAttributes.Hidden;

// "Yalnız oxu" atributunu götür
fileInfo.Attributes &= ~FileAttributes.ReadOnly;

// Bir neçə atributu eyni anda təyin et
fileInfo.Attributes = FileAttributes.ReadOnly | FileAttributes.Hidden;

4. Qovluqlarla inkişaf etmiş iş

Naxışlara görə faylları axtarmaq

GetFiles()GetDirectories() metodları naxışları qəbul edir və məzmunu filtr etməyə kömək edir.


var dir = new DirectoryInfo(@"C:\Projects");

if (dir.Exists)
{
    // Bütün mətn fayllarını tap
    var textFiles = dir.GetFiles("*.txt");
    Console.WriteLine($"Tapılan mətn faylları: {textFiles.Length}");
    
    // "temp" ilə başlayan faylları tap
    var tempFiles = dir.GetFiles("temp*");
    
    // Bütün şəkil fayllarını tap
    var imageExtensions = new[] { "*.jpg", "*.png", "*.gif", "*.bmp" };
    var allImages = imageExtensions.SelectMany(ext => dir.GetFiles(ext)).ToArray();
    
    Console.WriteLine($"Tapılan şəkillər: {allImages.Length}");
}

Alt qovluqlarda rekursiv axtarış

Bütün alt qovluqları gəzmək üçün SearchOption.AllDirectories-dən istifadə edin.


var dir = new DirectoryInfo(@"C:\Development");

// Bütün alt qovluqlarda .cs fayllarını tap
var csharpFiles = dir.GetFiles("*.cs", SearchOption.AllDirectories);
Console.WriteLine($"Ümumi tapılan .cs faylları: {csharpFiles.Length}");

// İlk 10 faylı və onların yollarını göstər
foreach (var file in csharpFiles.Take(10))
{
    Console.WriteLine($"{file.FullName} ({FormatFileSize(file.Length)})");
}

Qovluq məzmununun analizi

Sxematik analiz nümunəsi: fayl/qovluq sayı, ümumi ölçü, extension üzrə paylanma və ən böyük 5 fayl.


static void AnalyzeDirectory(DirectoryInfo dir)
{
    if (!dir.Exists)
    {
        Console.WriteLine("Qovluq mövcud deyil!");
        return;
    }
    
    var files = dir.GetFiles();
    var subdirs = dir.GetDirectories();
    
    Console.WriteLine($"Qovluğun analizi: {dir.FullName}");
    Console.WriteLine($"Fayllar: {files.Length}, Alt-qovluqlar: {subdirs.Length}");
    
    if (files.Length == 0)
    {
        Console.WriteLine("Fayl tapılmadı.");
        return;
    }
    
    long totalSize = files.Sum(f => f.Length);
    Console.WriteLine($"Faylların ümumi ölçüsü: {FormatFileSize(totalSize)}");
    
    // Extension üzrə qruplaşdırma
    var byExtension = files.GroupBy(f => f.Extension.ToLower())
                           .OrderByDescending(g => g.Sum(f => f.Length));
    
    Console.WriteLine("\nFayl tipləri üzrə paylanma:");
    foreach (var group in byExtension)
    {
        string ext = string.IsNullOrEmpty(group.Key) ? "(extension yoxdur)" : group.Key;
        long groupSize = group.Sum(f => f.Length);
        Console.WriteLine($"  {ext}: {group.Count()} fayl, {FormatFileSize(groupSize)}");
    }
    
    // Ən böyük 5 fayl
    var largestFiles = files.OrderByDescending(f => f.Length).Take(5);
    Console.WriteLine("\nƏn böyük fayllar:");
    foreach (var file in largestFiles)
    {
        Console.WriteLine($"  {file.Name}: {FormatFileSize(file.Length)}");
    }
}

5. Qovluğun ölçüsünü optimallaşdırılmış şəkildə hesablaması

Böyük qovluqlar üçün GetFiles()-in yerinə leniv enumerator-lardan EnumerateFiles()/EnumerateDirectories() istifadə edin, istisnaları işləyin və istəsəniz progress göstərin.


static long GetDirectorySizeAdvanced(DirectoryInfo dir, bool showProgress = false)
{
    long totalSize = 0;
    int fileCount = 0;
    var inaccessibleDirs = new List<string>();
    
    try
    {
        // Böyük qovluqlar üçün EnumerateFiles istifadə edirik (leniv yükləmə)
        foreach (var file in dir.EnumerateFiles())
        {
            try
            {
                totalSize += file.Length;
                fileCount++;
                
                if (showProgress && fileCount % 1000 == 0)
                {
                    Console.WriteLine($"Emal olunmuş fayl: {fileCount}, ölçü: {FormatFileSize(totalSize)}");
                }
            }
            catch (UnauthorizedAccessException)
            {
                // Fayl əlçatmazdır, keçir
            }
            catch (IOException)
            {
                // Faylı oxumaqda problem, keçir
            }
        }
        
        // Alt-qovluqları rekursiv emal edirik
        foreach (var subdir in dir.EnumerateDirectories())
        {
            try
            {
                totalSize += GetDirectorySizeAdvanced(subdir, showProgress);
            }
            catch (UnauthorizedAccessException)
            {
                inaccessibleDirs.Add(subdir.FullName);
            }
        }
    }
    catch (UnauthorizedAccessException)
    {
        inaccessibleDirs.Add(dir.FullName);
    }
    
    if (inaccessibleDirs.Any() && showProgress)
    {
        Console.WriteLine($"Əlçatan olmayan qovluq sayı: {inaccessibleDirs.Count}");
    }
    
    return totalSize;
}

// İstifadə
var targetDir = new DirectoryInfo(@"C:\Users");
Console.WriteLine("Qovluğun ölçüsünün hesablanmasına başlayırıq...");
long size = GetDirectorySizeAdvanced(targetDir, showProgress: true);
Console.WriteLine($"Ümumi ölçü: {FormatFileSize(size)}");

6. Metadata-nın praktik tətbiqləri

Tarixə görə faylları axtarmaq

Verilmiş dövrdə dəyişdirilmiş faylları axtarırıq (təmizlik, analiz və ya audit üçün rahat).


static void FindFilesByDate(DirectoryInfo dir, DateTime fromDate, DateTime toDate)
{
    Console.WriteLine($"Axtarış: {fromDate:yyyy-MM-dd} -- {toDate:yyyy-MM-dd}");
    
    var matchingFiles = dir.GetFiles("*", SearchOption.AllDirectories)
                           .Where(f => f.LastWriteTime >= fromDate && f.LastWriteTime <= toDate)
                           .OrderByDescending(f => f.LastWriteTime);
    
    Console.WriteLine($"Tapılan fayl sayı: {matchingFiles.Count()}");
    
    foreach (var file in matchingFiles.Take(20))
    {
        Console.WriteLine($"{file.LastWriteTime:yyyy-MM-dd HH:mm} - {file.Name} ({FormatFileSize(file.Length)})");
    }
}

// Nümunə: son həftədə dəyişdirilmiş faylları tap
var dir = new DirectoryInfo(@"C:\Documents");
var weekAgo = DateTime.Now.AddDays(-7);
FindFilesByDate(dir, weekAgo, DateTime.Now);

Duplicate olan faylları axtarmaq

Tez metod — ölçü üzrə qruplaşdırmaq. Dəqiqlik üçün məzmunun hash-larını da müqayisə etmək olar.


static void FindPotentialDuplicates(DirectoryInfo dir)
{
    Console.WriteLine($"Potensial duplicat faylların axtarışı: {dir.FullName}");
    
    var files = dir.GetFiles("*", SearchOption.AllDirectories)
                   .Where(f => f.Length > 0) // Boş faylları çıxırıq
                   .GroupBy(f => f.Length)
                   .Where(g => g.Count() > 1) // Bir neçə faylı olan qruplar
                   .OrderByDescending(g => g.Key); // Ölçüyə görə sıralama
    
    foreach (var sizeGroup in files.Take(10))
    {
        Console.WriteLine($"\nÖlçüsü {FormatFileSize(sizeGroup.Key)} olan fayllar ({sizeGroup.Count()} ədəd):");
        foreach (var file in sizeGroup)
        {
            Console.WriteLine($"  {file.FullName}");
            Console.WriteLine($"    Dəyişilib: {file.LastWriteTime:yyyy-MM-dd HH:mm:ss}");
        }
    }
}

Qovluqdakı dəyişikliklərin monitorinqi

Son N dəqiqədə dəyişdirilmiş faylları göstəririk.


static void MonitorRecentChanges(DirectoryInfo dir, int minutesBack = 60)
{
    var cutoffTime = DateTime.Now.AddMinutes(-minutesBack);
    
    var recentFiles = dir.GetFiles("*", SearchOption.AllDirectories)
                         .Where(f => f.LastWriteTime > cutoffTime)
                         .OrderByDescending(f => f.LastWriteTime);
    
    Console.WriteLine($"Son {minutesBack} dəqiqədə dəyişdirilmiş fayllar:");
    
    if (!recentFiles.Any())
    {
        Console.WriteLine("Dəyişiklik tapılmadı.");
        return;
    }
    
    foreach (var file in recentFiles)
    {
        var minutesAgo = (DateTime.Now - file.LastWriteTime).TotalMinutes;
        Console.WriteLine($"{file.Name} - {minutesAgo:F0} dəq. əvvəl ({FormatFileSize(file.Length)})");
    }
}

7. Valideyn qovluqlarla işləmək

Directory xassəsi FileInfo-də və Parent DirectoryInfo-də iyerarxiyada yuxarı qalxmağa imkan verir.


var file = new FileInfo(@"C:\Projects\MyApp\src\Program.cs");

Console.WriteLine($"Fayl: {file.Name}");
Console.WriteLine($"Qovluq: {file.Directory.Name}");
Console.WriteLine($"Valideyn qovluq: {file.Directory.Parent.Name}");
Console.WriteLine($"Layihənin root qovluğu: {file.Directory.Parent.Parent.Name}");

// İyerarxiyada root-a qədər qalxa bilərsiniz
var currentDir = file.Directory;
while (currentDir.Parent != null)
{
    Console.WriteLine($"Səviyyə: {currentDir.Name}");
    currentDir = currentDir.Parent;
}
Console.WriteLine($"Root: {currentDir.Name}");

8. Tələlər və tipik səhvlər

1. Keşlənmə. FileInfoDirectoryInfo obyektləri metadata-nı keşləyir. Obyekt yaradıldıqdan sonra dəyişibsə, məlumatlar köhnəlmiş ola bilər. Aktual məlumat üçün Refresh()-dən istifadə edin.


var file = new FileInfo("test.txt");
file.Refresh(); // Metadata-nı yenilə

2. İcazə istisnaları. Bəzi fayl və qovluqlara giriş yoxdur: UnauthorizedAccessException və digər giriş xətalarını işləyin.


try
{
    var files = new DirectoryInfo(path).GetFiles();
}
catch (UnauthorizedAccessException)
{
    Console.WriteLine("Giriş yoxdur");
}

3. Vaxt möhürləri. Fayl köçürüldükdə CreationTime dəyişə bilər, amma LastWriteTime qala bilər. Bu hesabatlar və sinxronizasiya alqoritmlərinə təsir edir.


File.Copy("a.txt", "b.txt");

4. Performans. GetFiles() hamısını bir dəfəyə yükləyir və böyük qovluqlarda yavaşlata bilər. Leniv enumeration üçün EnumerateFiles()-i üstün tutun.

Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION