Wie finde ich die neueste Datei in einem Verzeichnis mit .NET und ohne Schleife?
142
Ich muss die zuletzt geänderte Datei in einem Verzeichnis finden.
Ich weiß, dass ich jede Datei in einem Ordner durchlaufen und vergleichen kann File.GetLastWriteTime, aber gibt es eine bessere Möglichkeit, dies ohne Schleifen zu tun?
Nein, es gibt keinen besseren Weg, um Schleifen zu vermeiden. Selbst wenn Sie LINQ verwenden, wird die Schleife nur in eine tiefere Funktionalität ausgeblendet, die Sie nicht direkt sehen können.
Oliver
1
Wenn Sie die zuletzt geänderten Dateien im gesamten Dateisystem suchen möchten, ist das NTFS-Änderungsjournal hilfreich. Sehr, sehr schwer von C # zu verwenden.
Ben Voigt
Antworten:
318
wie wäre es mit so etwas ...
var directory =newDirectoryInfo("C:\\MyDirectory");var myFile =(from f in directory.GetFiles()orderby f.LastWriteTimedescendingselect f).First();// or...var myFile = directory.GetFiles().OrderByDescending(f => f.LastWriteTime).First();
Persönlich finde ich, dass die nicht gezuckerte Version leichter zu lesen ist:directory.GetFiles().OrderByDescending(f => f.LastWriteTime).First()
Jørn Schou-Rode
6
Ja, ich stimme auch die meiste Zeit zu - aber wenn ich Beispiele gebe, macht die Abfragesyntax ein bisschen offensichtlicher, dass es sich um eine Linq-Abfrage handelt. Ich werde das Beispiel mit beiden Optionen aktualisieren, um dies zu verdeutlichen.
Scott Ivey
3
Vielen Dank! Jetzt muss ich nur noch meinen Chef davon überzeugen, das Upgrade von .net 2.0 zu beschleunigen, damit ich Linq verwenden kann :)
Chris Klepeis
3
Sie können linq mit 2.0 SP1 mit ein wenig zusätzlicher Arbeit verwenden - verweisen Sie einfach auf die Datei System.Core.dll von 3.5 und setzen Sie sie auf "local kopieren"
Scott Ivey
8
Sollte dies nicht FirstOrDefault()stattdessen verwendet werden First()? Letzteres führt zu einem, InvalidOperationExceptionwenn das Verzeichnis leer ist.
Tobias J
20
Wenn Sie rekursiv suchen möchten, können Sie diesen schönen Code verwenden:
/// <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>privatestaticDateTimeGetLatestWriteTimeFromFileInDirectory(DirectoryInfo directoryInfo){if(directoryInfo ==null||!directoryInfo.Exists)returnDateTime.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>privatestaticFileInfoGetLatestWritenFileFileInDirectory(DirectoryInfo directoryInfo){if(directoryInfo ==null||!directoryInfo.Exists)returnnull;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;}
Ihr Code funktioniert aufgrund list<FileInfo> lastUpdateFile = null;
und später nicht, lastUpdatedFile.Add(file);sodass eine NullReference-Ausnahme ausgelöst wird. Arbeitsversion sollte sein:
Ich mache das ist eine Reihe meiner Apps und ich benutze eine Aussage wie diese:
var inputDirectory =newDirectoryInfo("\\Directory_Path_here");var myFile = inputDirectory.GetFiles().OrderByDescending(f => f.LastWriteTime).First();
Von hier aus haben Sie den Dateinamen für die zuletzt gespeicherte / hinzugefügte / aktualisierte Datei im Verzeichnis der Variablen "inputDirectory". Jetzt können Sie darauf zugreifen und damit machen, was Sie wollen.
Wenn Sie den Dateipfad wiederherstellen möchten und FirstOrDefault verwenden, weil möglicherweise keine Ergebnisse vorliegen, können Sie den nullbedingten Operator für die FullName-Eigenschaft verwenden. Dadurch erhalten Sie für Ihren Pfad "null" zurück, ohne die FileInfo von FirstOrDefault speichern zu müssen, bevor Sie FullName aufrufen. Zeichenfolge path = new DirectoryInfo (Pfad) .GetFiles (). OrderByDescending (o => o.LastWriteTime) .FirstOrDefault ()?. FullName;
Antworten:
wie wäre es mit so etwas ...
quelle
directory.GetFiles().OrderByDescending(f => f.LastWriteTime).First()
FirstOrDefault()
stattdessen verwendet werdenFirst()
? Letzteres führt zu einem,InvalidOperationException
wenn das Verzeichnis leer ist.Wenn Sie rekursiv suchen möchten, können Sie diesen schönen Code verwenden:
Nennen Sie es einfach so:
und das ist es. Gibt eine
FileInfo
Instanz zurück odernull
wenn das Verzeichnis leer ist.quelle
Wenn Sie das erste Muster oben erweitern möchten, können Sie den folgenden Code verwenden, wenn Sie nach einem bestimmten Muster suchen möchten:
quelle
Eine Nicht-LINQ-Version:
quelle
Kurz und einfach :
quelle
Es ist ein bisschen spät, aber ...
Ihr Code funktioniert aufgrund
list<FileInfo> lastUpdateFile = null;
und später nicht,lastUpdatedFile.Add(file);
sodass eine NullReference-Ausnahme ausgelöst wird. Arbeitsversion sollte sein:Vielen Dank
quelle
Sie können mit FileSystemWatcher auf neue Dateiaktivitäten reagieren .
quelle
Ein weiterer Ansatz, wenn Sie
Directory.EnumerateFiles
Dateien verwenden und lesen möchten, die zuletzt von first geändert wurden.quelle
Hier ist eine Version, die die neueste Datei aus jedem Unterverzeichnis abruft
quelle
quelle
Ich mache das ist eine Reihe meiner Apps und ich benutze eine Aussage wie diese:
Von hier aus haben Sie den Dateinamen für die zuletzt gespeicherte / hinzugefügte / aktualisierte Datei im Verzeichnis der Variablen "inputDirectory". Jetzt können Sie darauf zugreifen und damit machen, was Sie wollen.
Hoffentlich hilft das.
quelle