c# - ruta - Recuperando archivos del directorio que contiene gran cantidad de archivos
obtener ruta de carpeta c# (6)
Tengo un directorio que contiene casi 14,000,000 de muestras de audio en formato * .wav.
Todo el almacenamiento simple, sin subdirectorios.
Quiero recorrer los archivos, pero cuando uso DirectoryInfo.GetFiles()
en esa carpeta ¡toda la aplicación se congela por minutos!
¿Se puede hacer esto de otra manera? Tal vez leer 1000, procesarlos, luego tomar el próximo 1000 y así sucesivamente?
¿Has probado el método EnumerateFiles de la clase DirectoryInfo?
Como dice MSDN
Los métodos
EnumerateFiles
yGetFiles
difieren de la siguiente manera: Cuando utilizaEnumerateFiles
, puede comenzar a enumerar la colección de objetosFileInfo
antes de que se devuelva toda la colección; Cuando usaGetFiles
, debe esperar a que se devuelva toda la matriz de objetosFileInfo
para poder acceder a la matriz. Por lo tanto, cuando trabaja con muchos archivos y directorios,EnumerateFiles
puede ser más eficiente.
A esta cuestión de acceder a archivos de gran tamaño en un solo directorio muchas veces. Los subdirectorios son una buena opción, pero a veces incluso no ofrecen mucha ayuda a veces. Lo que hago ahora es crear un archivo de índice, un archivo de texto con los nombres de todos los archivos del directorio (siempre que esté creando archivos en ese directorio). Luego leo el archivo de índice y luego abro el archivo actual del directorio para procesarlo
Disfrutar.
public List<string> LoadPathToAllFiles(string pathToFolder, int numberOfFilesToReturn)
{
var DirInfo = new DirectoryInfo(pathToFolder);
var firstFiles = DirInfo.EnumerateFiles().Take(numberOfFilesToReturn).ToList();
return firstFiles.Select(l => l.FullName).ToList();
}
En .NET 4.0, Directory.EnumerateFiles(...)
es IEnumerable<string>
(en lugar de la string[]
de Directory.GetFiles(...)
), por lo que puede transmitir entradas en lugar de almacenarlas en el búfer; es decir
foreach(var file in Directory.EnumerateFiles(path)) {
// ...
}
Use las funciones Win32 Api FindFile para hacerlo sin bloquear la aplicación.
También puede llamar a Directory.GetFiles en System.Threading.Task (TPL) para evitar que se congele su UI.
está llegando a la limitación del sistema de archivos de Windows. Cuando la cantidad de archivos en un directorio crece hasta convertirse en un número grande (y 14M es mucho más allá de ese umbral), acceder al directorio se vuelve increíblemente lento. Realmente no importa si lee un archivo a la vez o 1000, es solo acceso al directorio.
Una forma de resolver esto es crear subdirectorios y separar sus archivos en grupos. Si cada directorio tiene 1000-5000 (supongo, pero puede experimentar con números reales), entonces debe obtener un rendimiento decente abriendo / creando / eliminando archivos.
Esta es la razón por la que si observa aplicaciones como Doxygen, que crea un archivo para cada clase, siguen este esquema y colocan todo en 2 niveles de subdirectorios que usan nombres aleatorios.