2009-11-12 22 views
23

Sądzę, że jest to dość powszechny wymóg w aplikacji, która zajmuje się rejestrowaniem. Pracuję nad aplikacją C# Windows, .NET 3.5.Usuwanie plików starszych niż pewna liczba dni

Moja aplikacja generuje mnóstwo plików dziennika, które mają aktualną datę umieszczoną w nazwie pliku, podobnie jak 20091112. Jaka byłaby najlepsza strategia usuwania plików starszych niż 30 dni. Jedno podejście, którego zamierzam użyć, polega na przechodzeniu między nazwami plików, wyodrębnianiu części daty, konwersji na obiekt DateTime i porównaniu z dzisiejszą datą. Czy jest w tym przypadku eleganckie rozwiązanie Wyrażenia regularnego :)? A może coś lepszego?

Odpowiedz

31
var files = new DirectoryInfo(@"c:\log").GetFiles("*.log"); 
foreach (var file in files) 
{ 
    if (DateTime.UtcNow - file.CreationTimeUtc > TimeSpan.FromDays(30)) 
    { 
     File.Delete(file.FullName); 
    } 
} 
+0

Po prostu muszę pobrać wszystkie obiekty FileInfo do pamięci, aby to zrobić. Zastanawiałem się nad otrzymaniem tylko tych nazw, ponieważ mają datę. Czy brzmi to jednak rozsądnie? – theraneman

+0

Sądzę, że mógłbyś współdziałać z 'FindFirstFile' i' FindNextFile' API lub spojrzeć na .NET 4.0, gdzie możesz użyć 'DirectoryInfo.EnumerateFiles' który zwraca' IEnumerable '. –

+2

Obiekty FileInfo nie są zbyt ciężkie - nie są uchwytem pliku ani niczym. PowerShell używa ich do wpisów katalogów przepływających przez potok na przykład. –

0

odjęcie dwóch DateTime obiektów daje TimeSpan obiekt, a następnie można po prostu sprawdzić jej TotalDays nieruchomości. Nie mogę wymyślić nic prostszego niż to.

1
string directoryPath = "/log"; // your log directory path 

foreach (string filePath in Directory.GetCreationTime(directoryPath)) 
{ 
    TimeSpan fileAge = File.GetLastWriteTime(filePath) - DateTime.Now; 
    if (fileAge.Days > 30) 
    { 
     File.Delete(filePath); 
    } 
} 
1

Jak rozumiem, chcesz użyć nazwy pliku zamiast modyfikacji czasu. W porządku.

Następnie kod jest tak:

foreach (string file in Directory.GetFiles(path)) 
    { 
     string fileNameOnly=Path.GetFileNameWithoutExtension(file); 
     DateTime fileDate = DateTime.ParseExact(fileNameOnly, "yyyyMMDD", CultureInfo.CurrentCulture); 
     if (DateTime.Now.Subtract(fileDate).TotalDays > MaxDays) 
      File.Delete(file); 
    } 
+0

To jest właśnie to, co mam teraz w moim kodzie. Po prostu pomyślałem, że mam wzorzec daty w zestawie ciągów, które muszę porównać, mogę być w stanie zatrudnić Regex, ale wydaje mi się, że muszę przejść przez pętlę foreach. – theraneman

1

[PowerShell] można wklej następujący w pliku PS1 i uczynić go częścią skryptu administratora, jeżeli odpowiada: -

param ($ ścieżka = $ (rzut "trzeba wskazać ścieżkę"), $ daysToRetain = $ (rzut "Należy wskazać, ile dni ma zostać zatrzymanych"))

dir $ path -r | ? {([datetime] :: UtcNow - $ _. CreationTimeUtc) .TotalDays -gt $ daysToRetain} | del

EDIT: A można użyć -match do analizowania nazwę, jeśli czujesz się za pomocą pliku czasy isnt słuszne

10

aktualizacja .net 4.0:

var files = new DirectoryInfo(directoryPath).GetFiles("*.log"); 
foreach (var file in files.Where(file => DateTime.UtcNow - file.CreationTimeUtc > TimeSpan.FromHours(2))) { 
    file.Delete(); 
} 
0
string[] files = Directory.GetFiles(path); 
foreach (string file in files) 
{ 
    if (File.GetLastWriteTime(file) < DateTime.Now.AddDays(-5)) 
    { 
     File.Delete(file); 
    } 
} 
+1

Proszę wziąć pod uwagę pewne wyjaśnienia, nie tylko surowy kod w swoich odpowiedziach. Możesz również wyjaśnić, co to jest, że twoja odpowiedź dodaje do istniejących odpowiedzi. – BartoszKP

Powiązane problemy