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 FileInfo və DirectoryInfo ilə əldə edə biləcəyiniz bir formadır.
| Xassə | Təsvir | Nümunə |
|---|---|---|
| Tam yol | Fayl/qovluğun tam adı | |
| Ad | Yoldan ayrı ad | |
| Extension | .txt, .csv, .jpg və s. | |
| Ölçü (Bytes) | Faylın baytla ölçüsü | |
| Yaradılma tarixi | Fayl/qovluq nə vaxt yaradılıb | |
| Dəyişmə tarixi | Məzmun son dəfə nə vaxt dəyişib | |
| Atributlar | Məsələn, yalnız oxu, gizli və s. | |
| Valideyn qovluq | Fayl/kataloqun yerləşdiyi qovluq | |
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, Name və Extension 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() və 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ə. FileInfo və DirectoryInfo 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.
GO TO FULL VERSION