Estoy tratando de usar el Directory.GetFiles()
método para recuperar una lista de archivos de varios tipos, como mp3
'sy jpg
' s. He intentado lo siguiente sin suerte:
Directory.GetFiles("C:\\path", "*.mp3|*.jpg", SearchOption.AllDirectories);
Directory.GetFiles("C:\\path", "*.mp3;*.jpg", SearchOption.AllDirectories);
¿Hay alguna manera de hacer esto en una llamada?
c#
filesystems
.net
Jason Z
fuente
fuente
Respuestas:
Para .NET 4.0 y posterior,
Para versiones anteriores de .NET,
editar: por favor lea los comentarios. La mejora que sugiere Paul Farry , y el problema de memoria / rendimiento que Christian.K señala son muy importantes.
fuente
s.ToLower().Endswith...
s.EndsWith(".mp3", StringComparison.OrdinalIgnoreCase)
Directory.GetFiles
conDirectory.EnumerateFiles
, msdn.microsoft.com/en-us/library/dd383571.aspx , lo que evitará los problemas de memoria que @ Christian.K menciona.Qué tal esto:
Lo encontré aquí (en los comentarios): http://msdn.microsoft.com/en-us/library/wz42302f.aspx
fuente
Parallel.ForEach
para ponerlos en paraleloSi tiene una gran lista de extensiones para verificar, puede usar lo siguiente. No quería crear muchas declaraciones OR, así que modifiqué lo que lette escribió.
fuente
Path.GetExtension
devuelve '.ext', no '* .ext' (al menos en 3.5+)..abc
, y que admite Extensions contiene.abcd
. Coincidirá, aunque no debería. Para arreglar:supportedExtensions = ".jpg|.abcd|";
con.Contains(Path.GetExtension(s).ToLower() + "|")
. Es decir, incluya su carácter separador en la prueba. IMPORTANTE: su carácter separador también debe estar después de la ÚLTIMA entrada en las excepciones admitidas.para
Tú podrías:
Directory.EnumerateFiles
para aumentar el rendimiento ( ¿Cuál es la diferencia entre Directory.EnumerateFiles y Directory.GetFiles? ).EndsWith("aspx", StringComparison.OrdinalIgnoreCase)
lugar de.ToLower().EndsWith("aspx")
)Pero el beneficio real de
EnumerateFiles
aparece cuando divide los filtros y combina los resultados:Se vuelve un poco más rápido si no tiene que convertirlos en globos (es decir,
exts = new[] {"*.mp3", "*.jpg"}
ya).Evaluación de rendimiento basada en la siguiente prueba de LinqPad (nota:
Perf
solo repite el delegado 10000 veces) https://gist.github.com/zaus/7454021(reenviado y extendido desde 'duplicado' ya que esa pregunta no solicitó específicamente LINQ: múltiples extensiones de archivo searchPattern para System.IO.Directory.GetFiles )
fuente
.FilterFiles(path, "jpg", "gif")
) es mejor que los "globos explícitos" (es decir.FilterFiles(path, "*.jpg", "*.gif")
).Sé que es una pregunta antigua pero LINQ: (.NET40 +)
fuente
file.ToLower()
para hacer coincidir fácilmente las extensiones de mayúsculas. Y por qué no extraer la extensión primero, para que Regex no tenga que examinar la ruta completa:Regex.IsMatch(Path.GetExtension(file).ToLower(), @"\.(wav|mp3|txt)");
También hay una solución de descenso que parece no tener sobrecarga de memoria o rendimiento y es bastante elegante:
fuente
Otra forma de usar Linq, pero sin tener que devolver todo y filtrar eso en la memoria.
En realidad son 2 llamadas
GetFiles()
, pero creo que es consistente con el espíritu de la pregunta y las devuelve en una enumerable.fuente
No Intenta lo siguiente:
Tomado de: http://blogs.msdn.com/markda/archive/2006/04/20/580075.aspx
fuente
Dejar
Entonces
o
fuente
No puedo usar el
.Where
método porque estoy programando en .NET Framework 2.0 (Linq solo es compatible con .NET Framework 3.5+).Código de abajo no es sensible a mayúsculas (por lo que
.CaB
o.cab
se enumeran también).fuente
La siguiente función busca en múltiples patrones, separados por comas. También puede especificar una exclusión, por ejemplo: "! Web.config" buscará todos los archivos y excluirá "web.config". Los patrones se pueden mezclar.
Uso:
fuente
fuente
file.Extension.ToLower()
Es una mala práctica.String.Equals(a, b, StringComparison.OrdinalIgnoreCase)
en .NET 2.0 (sin Linq):
Entonces úsalo:
fuente
fuente
Acabo de encontrar otra forma de hacerlo. Todavía no es una operación, sino tirarla para ver qué piensan otras personas al respecto.
fuente
Qué pasa
fuente
Haga las extensiones que desea una cadena, es decir, ".mp3.jpg.wma.wmf" y luego verifique si cada archivo contiene la extensión que desea. Esto funciona con .net 2.0 ya que no usa LINQ.
La ventaja de este enfoque es que puede agregar o quitar extensiones sin editar el código, es decir, para agregar imágenes png, simplemente escriba myExtensions = ". Jpg.mp3.png".
fuente
s
fuente
Nop ... creo que tienes que hacer tantas llamadas como los tipos de archivos que quieras.
Yo mismo crearía una función tomando una matriz en cadenas con las extensiones que necesito y luego iteraría en esa matriz haciendo todas las llamadas necesarias. Esa función devolvería una lista genérica de los archivos que coinciden con las extensiones que envié.
Espero eso ayude.
fuente
Tuve el mismo problema y no pude encontrar la solución correcta, así que escribí una función llamada GetFiles:
Esta función llamará
Directory.Getfiles()
solo una vez.Por ejemplo, llame a la función de esta manera:
EDITAR: Para obtener un archivo con múltiples extensiones, use este:
Por ejemplo, llame a la función de esta manera:
fuente
Me pregunto por qué hay tantas "soluciones" publicadas?
Si mi comprensión de novato sobre cómo funciona GetFiles es correcta, solo hay dos opciones y cualquiera de las soluciones anteriores se puede resumir en estas:
GetFiles, luego filtro: Rápido, pero un asesino de memoria debido al almacenamiento de sobrecarga hasta que se aplican los filtros
Filtre mientras GetFiles: más lento cuanto más filtros estén configurados, pero menor uso de memoria ya que no se almacena ninguna sobrecarga.
Esto se explica en una de las publicaciones anteriores con un punto de referencia impresionante: cada opción de filtro provoca una operación separada GetFile, por lo que la misma parte del disco duro se lee varias veces.
En mi opinión, la opción 1) es mejor, pero usar SearchOption.AllDirectories en carpetas como C: \ usaría grandes cantidades de memoria.
Por lo tanto, simplemente haría un submétodo recursivo que recorra todas las subcarpetas con la opción 1)
Esto debería causar solo 1 operación GetFiles en cada carpeta y, por lo tanto, ser rápido (Opción 1), pero use solo una pequeña cantidad de memoria ya que los filtros se aplican después de la lectura de cada subcarpeta -> la sobrecarga se elimina después de cada subcarpeta.
Por favor, corríjame si estoy equivocado. Soy, como dije, bastante nuevo en la programación, pero quiero obtener una comprensión más profunda de las cosas para eventualmente ser bueno en esto :)
fuente
Si está utilizando VB.NET (o importó la dependencia en su proyecto C #), en realidad existe un método conveniente que permite filtrar por múltiples extensiones:
En VB.NET se puede acceder a esto a través del espacio Mi nombre:
Desafortunadamente, estos métodos de conveniencia no admiten una variante vagamente evaluada como lo
Directory.EnumerateFiles()
hace.fuente
No sé qué solución es mejor, pero uso esto:
fuente
Aquí hay una manera simple y elegante de obtener archivos filtrados
fuente
O simplemente puede convertir la cadena de extensiones a Cadena ^
fuente
¡Usar el patrón de búsqueda GetFiles para filtrar la extensión no es seguro! Por ejemplo, tiene dos archivos Test1.xls y Test2.xlsx y desea filtrar el archivo xls utilizando el patrón de búsqueda * .xls, pero GetFiles devuelve Test1.xls y Test2.xlsx No estaba al tanto de esto y recibí un error en la producción entorno cuando algunos archivos temporales de repente se manejaron como archivos correctos. El patrón de búsqueda fue * .txt y los archivos temporales se llamaron * .txt20181028_100753898 Por lo tanto, no se puede confiar en el patrón de búsqueda, también debe agregar una verificación adicional en los nombres de archivo.
fuente