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 ?.
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 ?.
Réponses:
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();
directory.GetFiles().OrderByDescending(f => f.LastWriteTime).First()
FirstOrDefault()
place de First()
? Ce dernier provoquera un InvalidOperationException
si le répertoire est vide.
Si vous souhaitez effectuer une recherche récursive, vous pouvez utiliser ce magnifique morceau 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 FileInfo
instance ou null
si le répertoire est vide.
En développant le premier ci-dessus, si vous souhaitez rechercher un certain modèle, 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();
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;
}
c'est un peu tard mais ...
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:
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
Vous pouvez réagir à une nouvelle activité de fichier avec FileSystemWatcher .
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));
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;
}
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 cela pourra aider.