web-dev-qa-db-fra.com

Comment trouver le fichier le plus récent dans un répertoire utilisant .NET et sans boucle?

J'ai besoin de trouver le dernier fichier modifié dans un répertoire.

Je sais que je peux parcourir tous les fichiers d’un dossier et comparer File.GetLastWriteTime, mais y a-t-il une meilleure façon de le faire sans boucler ?.

127
Chris Klepeis

que diriez-vous quelque chose comme ça...

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();
286
Scott Ivey

Si vous souhaitez effectuer une recherche récursive, vous pouvez utiliser ce bel élément de code:

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();                        
}

Appelez-le simplement de la manière suivante:

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

et c'est tout. Renvoie une instance FileInfo ou null si le répertoire est vide.

19

En développant le premier ci-dessus, si vous souhaitez rechercher un certain motif, vous pouvez utiliser le code suivant:

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

Une version non-LINQ:

/// <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;
}
10
TimothyP

c'est un peu tard mais ...

votre code ne fonctionnera pas, à cause de list<FileInfo> lastUpdateFile = null; et de la suite lastUpdatedFile.Add(file);, donc une exception NullReference sera levée. La version de travail devrait être:

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;
}

Merci

3
Oleg Karbushev

court et simple:

new DirectoryInfo(path).GetFiles().OrderByDescending(o => o.LastWriteTime).FirstOrDefault();
3
Jacob

Vous pouvez réagir à la nouvelle activité de fichier avec FileSystemWatcher .

2
Scott Marlowe

Voici une version qui récupère le fichier le plus récent de chaque sous-répertoire

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));
1
Michael Bahig

Une autre approche si vous utilisez Directory.EnumerateFiles et que vous voulez lire les derniers fichiers modifiés en premier.

foreach (string file in Directory.EnumerateFiles(fileDirectory, fileType).OrderByDescending(f => new FileInfo(f).LastWriteTime))

}
1
Gaurravs

Je fais ceci est un tas de mes applications et j'utilise une déclaration comme celle-ci:

  var inputDirectory = new DirectoryInfo("\\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.

J'espère que ça t'as aidé.

0
JasonR
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;
}
0
Sylver1981