Nie, nie ma lepszego sposobu na uniknięcie zapętlenia. Nawet użycie LINQ po prostu ukrywa pętlę w jakiejś głębszej funkcjonalności, w której nie można jej zobaczyć bezpośrednio.
Oliver
1
Jeśli chcesz znaleźć ostatnio zmodyfikowane pliki w całym systemie plików, przydatny byłby dziennik zmian NTFS. Jednak bardzo trudny w użyciu w C #.
Ben Voigt,
Odpowiedzi:
318
co powiesz na coś takiego ...
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();
Osobiście uważam, że wersja bez cukru jest łatwiejsza do odczytania:directory.GetFiles().OrderByDescending(f => f.LastWriteTime).First()
Jørn Schou-Rode
6
tak, w większości przypadków też się z tym zgadzam - ale podając przykłady składnia zapytania sprawia, że jest to nieco bardziej oczywiste, że jest to zapytanie linq. Zaktualizuję przykład z obiema opcjami, aby wyjaśnić.
Scott Ivey
3
Dzięki! Teraz muszę tylko przekonać szefa, aby przyspieszył proces aktualizacji z .net 2.0, abym mógł używać Linq :)
Chris Klepeis
3
możesz używać linq z 2.0 SP1 z odrobiną dodatkowej pracy - po prostu odwołaj się do pliku System.Core.dll z 3.5 i ustaw go na „kopiuj lokalnie”
Scott Ivey
8
Czy nie powinno to używać FirstOrDefault()zamiast First()? Ta ostatnia spowoduje InvalidOperationException, że katalog jest pusty.
Tobias J
20
Jeśli chcesz wyszukiwać rekurencyjnie, możesz użyć tego pięknego fragmentu kodu:
/// <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;}
Twój kod nie będzie działał, ponieważ list<FileInfo> lastUpdateFile = null;
i później lastUpdatedFile.Add(file);zostanie zgłoszony wyjątek NullReference. Wersja robocza powinna być:
Robię to z kilku moich aplikacji i używam następującego oświadczenia:
var inputDirectory =newDirectoryInfo("\\Directory_Path_here");var myFile = inputDirectory.GetFiles().OrderByDescending(f => f.LastWriteTime).First();
Stąd będziesz mieć nazwę pliku dla ostatnio zapisanego / dodanego / zaktualizowanego pliku w katalogu zmiennej "inputDirectory". Teraz możesz uzyskać do niego dostęp i robić z nim, co chcesz.
Aby to dodać, jeśli Twoim celem jest odzyskanie ścieżki pliku i używasz FirstOrDefault, ponieważ możliwe jest, że nie ma żadnych wyników, możesz użyć operatora warunkowego zerowego we właściwości FullName. Spowoduje to zwrócenie „null” dla twojej ścieżki bez konieczności zapisywania FileInfo z FirstOrDefault przed wywołaniem FullName. string path = new DirectoryInfo (path) .GetFiles (). OrderByDescending (o => o.LastWriteTime) .FirstOrDefault () ?. FullName;
Odpowiedzi:
co powiesz na coś takiego ...
źródło
directory.GetFiles().OrderByDescending(f => f.LastWriteTime).First()
FirstOrDefault()
zamiastFirst()
? Ta ostatnia spowodujeInvalidOperationException
, że katalog jest pusty.Jeśli chcesz wyszukiwać rekurencyjnie, możesz użyć tego pięknego fragmentu kodu:
Po prostu nazwij to w następujący sposób:
i to wszystko. Zwraca
FileInfo
instancję lubnull
jeśli katalog jest pusty.źródło
Rozwijając pierwszy z powyższych, jeśli chcesz wyszukać określony wzorzec, możesz użyć następującego kodu:
źródło
Wersja inna niż LINQ:
źródło
Krótko i prosto :
źródło
jest trochę późno, ale ...
Twój kod nie będzie działał, ponieważ
list<FileInfo> lastUpdateFile = null;
i późniejlastUpdatedFile.Add(file);
zostanie zgłoszony wyjątek NullReference. Wersja robocza powinna być:Dzięki
źródło
Możesz reagować na nową aktywność plików za pomocą FileSystemWatcher .
źródło
Inne podejście, jeśli używasz
Directory.EnumerateFiles
i chcesz czytać pliki w najnowszej modyfikacji przez pierwsze.źródło
Oto wersja, która pobiera najnowszy plik z każdego podkatalogu
źródło
źródło
Robię to z kilku moich aplikacji i używam następującego oświadczenia:
Stąd będziesz mieć nazwę pliku dla ostatnio zapisanego / dodanego / zaktualizowanego pliku w katalogu zmiennej "inputDirectory". Teraz możesz uzyskać do niego dostęp i robić z nim, co chcesz.
Mam nadzieję, że to pomoże.
źródło