2009-07-24 7 views
97

Ich muss die zuletzt geänderte Datei in einem Verzeichnis finden.Wie finde ich die letzte Datei in einem Verzeichnis mit .NET und ohne Schleifen?

Ich weiß, ich kann durch jede Datei in einem Ordner durchlaufen und File.GetLastWriteTime vergleichen, aber gibt es eine bessere Möglichkeit, dies ohne Schleife zu tun ?.

+15

Nein, es gibt keinen besseren Weg, die verhindert Looping. Selbst wenn Sie LINQ verwenden, wird die Schleife nur in eine tiefere Funktionalität ausgeblendet, in der Sie sie nicht direkt sehen können. – Oliver

+1

Wenn Sie die zuletzt geänderten Dateien im gesamten Dateisystem finden möchten, ist das NTFS Change Journal nützlich. Sehr sehr schwer von C# zu verwenden. –

Antwort

220

wie wäre es so etwas wie ...

var directory = new DirectoryInfo("C:\\MyDirectory"); 
var myFile = (from f in directory.GetFiles() 
      orderby f.LastWriteTime descending 
      select f).First(); 

// or... 
var myFile = directory.GetFiles() 
      .OrderByDescending(f => f.LastWriteTime) 
      .First(); 
+66

Persönlich finde ich, dass die nicht gezuckerte Version einfacher zu lesen ist: 'directory.GetFiles(). OrderByDescending (f => f.LastWriteTime) .First()' –

+5

ja, ich stimme der meiste Zeit auch zu - aber wann Geben Sie Beispiele, die Abfrage-Syntax macht es ein bisschen mehr offensichtlich, dass es eine Linq-Abfrage ist. Ich werde das Beispiel mit beiden Optionen zur Klärung aktualisieren. –

+3

Danke! Jetzt muss ich nur meinen Chef davon überzeugen, den Prozess der Aktualisierung uns von .net 2.0 zu beschleunigen, damit ich Linq verwenden kann :) –

1

Sie können auf neue Dateiaktivität mit FileSystemWatcher reagieren.

+1

Es funktioniert nicht, da eine Datei geändert werden kann, während ihre Anwendung nicht ausgeführt wird. –

+1

er gab diese Art von Detail nicht ... Woher wissen wir, dass es keine dauerhafte App ist? –

+1

Wir nicht, aber Scott hat eine bessere Lösung, was in beiden Fällen funktioniert. – Badaro

9

Eine nicht-LINQ-Version:

/// <summary> 
/// Returns latest writen file from the specified directory. 
/// If the directory does not exist or doesn't contain any file, DateTime.MinValue is returned. 
/// </summary> 
/// <param name="directoryInfo">Path of the directory that needs to be scanned</param> 
/// <returns></returns> 
private static DateTime GetLatestWriteTimeFromFileInDirectory(DirectoryInfo directoryInfo) 
{ 
    if (directoryInfo == null || !directoryInfo.Exists) 
     return DateTime.MinValue; 

    FileInfo[] files = directoryInfo.GetFiles(); 
    DateTime lastWrite = DateTime.MinValue; 

    foreach (FileInfo file in files) 
    { 
     if (file.LastWriteTime > lastWrite) 
     { 
      lastWrite = file.LastWriteTime; 
     } 
    } 

    return lastWrite; 
} 

/// <summary> 
/// Returns file's latest writen timestamp from the specified directory. 
/// If the directory does not exist or doesn't contain any file, null is returned. 
/// </summary> 
/// <param name="directoryInfo">Path of the directory that needs to be scanned</param> 
/// <returns></returns> 
private static FileInfo GetLatestWritenFileFileInDirectory(DirectoryInfo directoryInfo) 
{ 
    if (directoryInfo == null || !directoryInfo.Exists) 
     return null; 

    FileInfo[] files = directoryInfo.GetFiles(); 
    DateTime lastWrite = DateTime.MinValue; 
    FileInfo lastWritenFile = null; 

    foreach (FileInfo file in files) 
    { 
     if (file.LastWriteTime > lastWrite) 
     { 
      lastWrite = file.LastWriteTime; 
      lastWritenFile = file; 
     } 
    } 
    return lastWritenFile; 
} 
+1

Sorry, habe nicht die Tatsache gesehen, dass du nicht loopen willst. Wie auch immer ... vielleicht hilft es jemandem, etwas ähnliches zu suchen – TimothyP

+3

Dieser Code wird nicht kompiliert. - lastUpdatedFile sollte kein Array sein. - Der Initialwert für lastUpdate ist ungültig (0001/0/0). –

18

Wenn Sie rekursiv durchsuchen möchten, können Sie dieses schöne Stück Code verwenden:

public static FileInfo GetNewestFile(DirectoryInfo directory) { 
    return directory.GetFiles() 
     .Union(directory.GetDirectories().Select(d => GetNewestFile(d))) 
     .OrderByDescending(f => (f == null ? DateTime.MinValue : f.LastWriteTime)) 
     .FirstOrDefault();       
} 

Rufen Sie einfach den folgenden Weg:

FileInfo newestFile = GetNewestFile(new DirectoryInfo(@"C:\directory\")); 

und das war's. Gibt eine FileInfo Instanz oder null zurück, wenn das Verzeichnis leer ist.

+8

Oder Sie können die Option [rekursive Suche] (http://msdn.microsoft.com/en-us/library/ms143327 (v = vs.110) .aspx) verwenden. – ricksmt

+2

Netter Code. es ist wirklich hilfreich. – Monika

0
private List<FileInfo> GetLastUpdatedFileInDirectory(DirectoryInfo directoryInfo) 
{ 
    FileInfo[] files = directoryInfo.GetFiles(); 
    List<FileInfo> lastUpdatedFile = null; 
    DateTime lastUpdate = new DateTime(1, 0, 0); 
    foreach (FileInfo file in files) 
    { 
     if (file.LastAccessTime > lastUpdate) 
     { 
      lastUpdatedFile.Add(file); 
      lastUpdate = file.LastAccessTime; 
     } 
    } 

    return lastUpdatedFile; 
} 
+2

Eine Erklärung wäre schön gewesen, hier –

+1

Ich denke, der Code ist ziemlich klar und braucht keine Erklärungen. – vikasde

14

oben auf dem ersten Erweiterung, wenn Sie nach einem bestimmten Muster suchen mögen Sie den folgenden Code verwenden:

string pattern = "*.txt" 
var dirInfo = new DirectoryInfo(directory); 
var file = (from f in dirInfo.GetFiles(pattern) orderby f.LastWriteTime descending select f).First(); 
1

Hier ist eine Version, die die aktuellste Datei von jedem Unterverzeichnis wird

List<string> reports = new List<string>();  
DirectoryInfo directory = new DirectoryInfo(ReportsRoot); 
directory.GetFiles("*.xlsx", SearchOption.AllDirectories).GroupBy(fl => fl.DirectoryName) 
.ForEach(g => reports.Add(g.OrderByDescending(fi => fi.LastWriteTime).First().FullName)); 
2

es ist ein bisschen spät, aber ...

Ihr Code wird nicht funktionieren, b Ursache von list<FileInfo> lastUpdateFile = null; und später lastUpdatedFile.Add(file); so wird NullReference Ausnahme ausgelöst. Arbeits Version sollte sein:

private List<FileInfo> GetLastUpdatedFileInDirectory(DirectoryInfo directoryInfo) 
{ 
    FileInfo[] files = directoryInfo.GetFiles(); 
    List<FileInfo> lastUpdatedFile = new List<FileInfo>(); 
    DateTime lastUpdate = DateTime.MinValue; 
    foreach (FileInfo file in files) 
    { 
     if (file.LastAccessTime > lastUpdate) 
     { 
      lastUpdatedFile.Add(file); 
      lastUpdate = file.LastAccessTime; 
     } 
    } 

    return lastUpdatedFile; 
} 

Dank

0

ich tun, das ist ein paar meiner Apps und ich verwende eine Anweisung wie folgt:

var inputDirectory = new DirectoryInfo("\\Directory_Path_here"); 
    var myFile = inputDirectory.GetFiles().OrderByDescending(f => f.LastWriteTime).First(); 

Von hier aus werden Sie die Dateinamen haben für die zuletzt gespeicherte/hinzugefügte/aktualisierte Datei im Verzeichnis der Variablen "inputDirectory". Jetzt können Sie darauf zugreifen und tun, was Sie wollen.

Hoffe, dass hilft.

1

Kurz und knapp:

new DirectoryInfo(path).GetFiles().OrderByDescending(o => o.LastWriteTime).FirstOrDefault(); 
Verwandte Themen