No, no hay mejor manera de evitar bucles. Incluso usar LINQ solo oculta el bucle en una funcionalidad más profunda donde no se puede ver directamente.
Oliver
1
Si desea encontrar los archivos modificados más recientemente en todo el sistema de archivos, el Diario de cambios de NTFS sería útil. Sin embargo, es muy, muy difícil de usar desde C #.
Ben Voigt
Respuestas:
318
Qué tal algo como esto...
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();
Personalmente, encuentro que la versión no azucarada es más fácil de leer:directory.GetFiles().OrderByDescending(f => f.LastWriteTime).First()
Jørn Schou-Rode
66
Sí, también estoy de acuerdo la mayor parte del tiempo, pero al dar ejemplos, la sintaxis de la consulta hace que sea un poco más obvio que es una consulta linq. Actualizaré el ejemplo con ambas opciones para aclarar.
Scott Ivey
3
¡Gracias! Ahora solo necesito convencer a mi jefe para que agilice el proceso de actualización de .net 2.0 para poder usar Linq :)
Chris Klepeis
3
puede usar linq con 2.0 SP1 con un poco de trabajo extra: solo haga referencia al archivo System.Core.dll de 3.5 y configúrelo para "copiar localmente"
Scott Ivey,
8
¿No debería este uso en FirstOrDefault()lugar de First()? Este último causará un InvalidOperationExceptionsi el directorio está vacío.
Tobias J
20
Si desea buscar de forma recursiva, puede usar este hermoso código:
/// <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;}
su código no funcionará debido a list<FileInfo> lastUpdateFile = null;
y más tarde, lastUpdatedFile.Add(file);por lo que se generará una excepción NullReference. La versión de trabajo debe ser:
Hago esto es un montón de mis aplicaciones y uso una declaración como esta:
var inputDirectory =newDirectoryInfo("\\Directory_Path_here");var myFile = inputDirectory.GetFiles().OrderByDescending(f => f.LastWriteTime).First();
Desde aquí tendrá el nombre del archivo guardado / agregado / actualizado más recientemente en el directorio de la variable "inputDirectory". Ahora puede acceder a él y hacer lo que quiera con él.
Para agregar a esto, si su objetivo es recuperar la ruta del archivo, y está usando FirstOrDefault porque es posible que no haya resultados, puede usar el operador condicional nulo en la propiedad FullName. Esto lo devolverá "nulo" para su ruta sin tener que guardar el FileInfo de FirstOrDefault antes de llamar a FullName. string path = new DirectoryInfo (ruta) .GetFiles (). OrderByDescending (o => o.LastWriteTime) .FirstOrDefault ()? FullName;
Respuestas:
Qué tal algo como esto...
fuente
directory.GetFiles().OrderByDescending(f => f.LastWriteTime).First()
FirstOrDefault()
lugar deFirst()
? Este último causará unInvalidOperationException
si el directorio está vacío.Si desea buscar de forma recursiva, puede usar este hermoso código:
Solo llámalo de la siguiente manera:
y eso es. Devuelve una
FileInfo
instancia onull
si el directorio está vacío.fuente
Ampliando el primero de arriba, si desea buscar un cierto patrón, puede usar el siguiente código:
fuente
Una versión no LINQ:
fuente
Corto y simple :
fuente
es un poco tarde pero ...
su código no funcionará debido a
list<FileInfo> lastUpdateFile = null;
y más tarde,lastUpdatedFile.Add(file);
por lo que se generará una excepción NullReference. La versión de trabajo debe ser:Gracias
fuente
Puede reaccionar a la nueva actividad de archivo con FileSystemWatcher .
fuente
Otro enfoque si está utilizando
Directory.EnumerateFiles
y desea leer los archivos modificados por primera vez.fuente
Aquí hay una versión que obtiene el archivo más reciente de cada subdirectorio
fuente
fuente
Hago esto es un montón de mis aplicaciones y uso una declaración como esta:
Desde aquí tendrá el nombre del archivo guardado / agregado / actualizado más recientemente en el directorio de la variable "inputDirectory". Ahora puede acceder a él y hacer lo que quiera con él.
Espero que ayude.
fuente