Comment trouver le fichier le plus récent dans un répertoire en utilisant .NET, et sans boucle?
142
J'ai besoin de trouver le fichier le plus récemment modifié dans un répertoire.
Je sais que je peux parcourir chaque fichier dans un dossier et comparer File.GetLastWriteTime, mais y a-t-il une meilleure façon de le faire sans boucle ?.
Non, il n'y a pas de meilleur moyen pour éviter les boucles. Même l'utilisation de LINQ masque simplement la boucle dans des fonctionnalités plus profondes où vous ne pouvez pas la voir directement.
Oliver
1
Si vous vouliez trouver le ou les fichiers les plus récemment modifiés sur l'ensemble du système de fichiers, le journal des modifications NTFS serait utile. Très très difficile à utiliser à partir de C #, cependant.
Ben Voigt
Réponses:
318
Que diriez-vous quelque chose comme ça...
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();
Personnellement, je trouve que la version non sucrée est plus facile à lire:directory.GetFiles().OrderByDescending(f => f.LastWriteTime).First()
Jørn Schou-Rode
6
oui, je suis d'accord la plupart du temps aussi - mais quand on donne des exemples, la syntaxe de la requête rend un peu plus évident qu'il s'agit d'une requête linq. Je vais mettre à jour l'exemple avec les deux options pour clarifier.
Scott Ivey
3
Merci! Maintenant, j'ai juste besoin de convaincre mon patron d'accélérer le processus de mise à niveau de .net 2.0 afin que je puisse utiliser Linq :)
Chris Klepeis
3
vous pouvez utiliser linq avec 2.0 SP1 avec un peu de travail supplémentaire - il suffit de référencer le fichier System.Core.dll de 3.5 et de le définir sur "copier local"
Scott Ivey
8
Ne devrait-il pas utiliser à la FirstOrDefault()place de First()? Ce dernier provoquera un InvalidOperationExceptionsi le répertoire est vide.
Tobias J
20
Si vous souhaitez effectuer une recherche récursive, vous pouvez utiliser ce magnifique morceau de code:
/// <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;}
Désolé, je n'ai pas vu le fait que vous ne vouliez pas faire de boucle. Quoi qu'il en soit ... peut-être que cela aidera quelqu'un à chercher quelque chose de similaire
TimothyP
3
Ce code ne compile pas. - lastUpdatedFile ne doit pas être un tableau. - La valeur initiale de lastUpdate n'est pas valide (0001/0/0).
votre code ne fonctionnera pas, à cause de list<FileInfo> lastUpdateFile = null;
et plus tard lastUpdatedFile.Add(file);, une exception NullReference sera donc levée. La version de travail doit être:
Je fais ceci est un tas de mes applications et j'utilise une déclaration comme celle-ci:
var inputDirectory =newDirectoryInfo("\\Directory_Path_here");var myFile = inputDirectory.GetFiles().OrderByDescending(f => f.LastWriteTime).First();
De là, vous aurez le nom du fichier le plus récemment enregistré / ajouté / mis à jour dans le répertoire de la variable "inputDirectory". Vous pouvez maintenant y accéder et en faire ce que vous voulez.
Pour ajouter à cela, si votre objectif est de récupérer le chemin du fichier et que vous utilisez FirstOrDefault car il est possible qu'il n'y ait aucun résultat, vous pouvez utiliser l'opérateur conditionnel null sur la propriété FullName. Cela vous retournera "null" pour votre chemin sans avoir à enregistrer le FileInfo de FirstOrDefault avant d'appeler FullName. string path = new DirectoryInfo (chemin) .GetFiles (). OrderByDescending (o => o.LastWriteTime) .FirstOrDefault () ?. FullName;
Réponses:
Que diriez-vous quelque chose comme ça...
la source
directory.GetFiles().OrderByDescending(f => f.LastWriteTime).First()
FirstOrDefault()
place deFirst()
? Ce dernier provoquera unInvalidOperationException
si le répertoire est vide.Si vous souhaitez effectuer une recherche récursive, vous pouvez utiliser ce magnifique morceau de code:
Appelez-le simplement de la manière suivante:
et c'est tout. Renvoie une
FileInfo
instance ounull
si le répertoire est vide.la source
En développant le premier ci-dessus, si vous souhaitez rechercher un certain modèle, vous pouvez utiliser le code suivant:
la source
Une version non LINQ:
la source
Bref et simple :
la source
c'est un peu tard mais ...
votre code ne fonctionnera pas, à cause de
list<FileInfo> lastUpdateFile = null;
et plus tardlastUpdatedFile.Add(file);
, une exception NullReference sera donc levée. La version de travail doit être:Merci
la source
Vous pouvez réagir à une nouvelle activité de fichier avec FileSystemWatcher .
la source
Une autre approche si vous utilisez
Directory.EnumerateFiles
et souhaitez lire les fichiers dans la dernière modification par en premier.la source
Voici une version qui récupère le fichier le plus récent de chaque sous-répertoire
la source
la source
Je fais ceci est un tas de mes applications et j'utilise une déclaration comme celle-ci:
De là, vous aurez le nom du fichier le plus récemment enregistré / ajouté / mis à jour dans le répertoire de la variable "inputDirectory". Vous pouvez maintenant y accéder et en faire ce que vous voulez.
J'espère que cela pourra aider.
la source