¿Cómo hacer una recursiva lista de todos los archivos en un directorio y directorios secundarios en C#?Cómo recursivamente enumerar todos los archivos en un directorio en C#?
Respuesta
This artículo cubre todo lo que necesita. Excepto en lugar de buscar los archivos y comparar nombres, simplemente imprima los nombres.
Puede ser modificado así:
static void DirSearch(string sDir)
{
try
{
foreach (string d in Directory.GetDirectories(sDir))
{
foreach (string f in Directory.GetFiles(d))
{
Console.WriteLine(f);
}
DirSearch(d);
}
}
catch (System.Exception excpt)
{
Console.WriteLine(excpt.Message);
}
}
Este método no muestra archivos para el directorio inicial, solo son subdirectores y más bajo. Me gustaría mover GetFiles fuera de GetDirectories – GONeale
A veces uno no quiere los archivos para el directorio inicial, en cuyo caso esto es perfecto para estructuras razonablemente pequeñas. Para listas muy grandes, use algo como la solución de Marc Gravell: http://stackoverflow.com/a/929418/91189 –
@GONeale es correcto. Es mucho menos plausible para un usuario no esperar la lista de archivos del directorio raíz de entrada. La entrada de palabra es la clave aquí. Ha sido ingresado por una razón. –
Nótese que en .NET 4.0 no son (supuestamente) (en vez de basadas en matrices) en funciones de archivo construidas a base de iterador:
foreach (string file in Directory.EnumerateFiles(
path, "*.*", SearchOption.AllDirectories))
{
Console.WriteLine(file);
}
Por el momento usaría algo como a continuación; el método recursivo incorporado se rompe demasiado fácilmente si no tiene acceso a un solo subdirectorio ...; el uso de Queue<string>
evita demasiada recursividad de la pila de llamadas, y el bloque iterador nos evita tener una gran matriz.
static void Main() {
foreach (string file in GetFiles(SOME_PATH)) {
Console.WriteLine(file);
}
}
static IEnumerable<string> GetFiles(string path) {
Queue<string> queue = new Queue<string>();
queue.Enqueue(path);
while (queue.Count > 0) {
path = queue.Dequeue();
try {
foreach (string subDir in Directory.GetDirectories(path)) {
queue.Enqueue(subDir);
}
}
catch(Exception ex) {
Console.Error.WriteLine(ex);
}
string[] files = null;
try {
files = Directory.GetFiles(path);
}
catch (Exception ex) {
Console.Error.WriteLine(ex);
}
if (files != null) {
for(int i = 0 ; i < files.Length ; i++) {
yield return files[i];
}
}
}
}
¿Cómo funcionará esto cuando se trata de enlaces simbólicos y similares? – soandos
Tenga en cuenta los espacios en blanco como el nombre del directorio => http://stackoverflow.com/q/5368054/2336304 – SerG
@soandos En el punto de repetición recursivo EnumerateFiles lanza IOException "El nombre del archivo no puede ser resuelto por el sistema" – SerG
En .NET 4.5, al menos, hay una versión que es mucho más corto y tiene la ventaja añadida de evaluar los criterios de archivos para su inclusión en la lista:
/// </remarks>
public static IEnumerable<string> GetAllFiles(string path, Func<FileInfo, bool> checkFile = null)
{
string mask = Path.GetFileName(path);
if (string.IsNullOrEmpty(mask))
mask = "*.*";
path = Path.GetDirectoryName(path);
string[] files = Directory.GetFiles(path, mask, SearchOption.AllDirectories);
foreach (string file in files)
{
if (checkFile == null || checkFile(new FileInfo(file)))
yield return file;
}
}
Uso como:
string folder = Config.TestInput();
string mask = folder + "*.*";
var list = UT.GetAllFiles(mask, (info) => Path.GetExtension(info.Name) == ".html").ToList();
Assert.AreNotEqual(0, list.Count);
var lastQuarter = DateTime.Now.AddMonths(-3);
list = UT.GetAllFiles(mask, (info) => info.CreationTime >= lastQuarter).ToList();
Assert.AreNotEqual(0, list.Count);
Algunas respuestas excelentes, pero estas respuestas no solucionaron mi problema.
En cuanto surge un problema de permiso de carpeta: "Permiso denegado", el código falla. Esto es lo que solía hacer con el tema "Permiso denegado":
private int counter = 0;
private string[] MyDirectories = Directory.GetDirectories("C:\\");
private void ScanButton_Click(object sender, EventArgs e)
{
Thread MonitorSpeech = new Thread(() => ScanFiles());
MonitorSpeech.Start();
}
private void ScanFiles()
{
string CurrentDirectory = string.Empty;
while (counter < MyDirectories.Length)
{
try
{
GetDirectories();
CurrentDirectory = MyDirectories[counter++];
}
catch
{
if (!this.IsDisposed)
{
listBox1.Invoke((MethodInvoker)delegate { listBox1.Items.Add("Access Denied to : " + CurrentDirectory); });
}
}
}
}
private void GetDirectories()
{
foreach (string directory in MyDirectories)
{
GetFiles(directory);
}
}
private void GetFiles(string directory)
{
try
{
foreach (string file in Directory.GetFiles(directory, "*"))
{
listBox1.Invoke((MethodInvoker)delegate { listBox1.Items.Add(file); });
}
}
catch
{
listBox1.Invoke((MethodInvoker)delegate { listBox1.Items.Add("Access Denied to : " + directory); });
}
}
Espero que esto ayude a los demás.
En Marco 2.0 se puede utilizar (archivos a esta lista de carpeta raíz, lo mejor es la respuesta más popular):
static void DirSearch(string dir)
{
try
{
foreach (string f in Directory.GetFiles(dir))
Console.WriteLine(f);
foreach (string d in Directory.GetDirectories(dir))
{
Console.WriteLine(d);
DirSearch(d);
}
}
catch (System.Exception ex)
{
Console.WriteLine(ex.Message);
}
}
Aquí está mi punto de vista en él, sobre la base de Hernaldo de, si usted necesita para encontrar archivos con nombres de un cierto patrón, como archivos XML que en algún lugar de su nombre contienen una cadena en particular:
// call this like so: GetXMLFiles("Platypus", "C:\\");
public static List<string> GetXMLFiles(string fileType, string dir)
{
string dirName = dir;
var fileNames = new List<String>();
try
{
foreach (string f in Directory.GetFiles(dirName))
{
if ((f.Contains(fileType)) && (f.Contains(".XML")))
{
fileNames.Add(f);
}
}
foreach (string d in Directory.GetDirectories(dirName))
{
GetXMLFiles(fileType, d);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return fileNames;
}
Aquí es una versión de código de arcilla B. Shannon no estática de Excel-archivos:
class ExcelSearcher
{
private List<string> _fileNames;
public ExcelSearcher(List<string> filenames)
{
_fileNames = filenames;
}
public List<string> GetExcelFiles(string dir, List<string> filenames = null)
{
string dirName = dir;
var dirNames = new List<string>();
if (filenames != null)
{
_fileNames.Concat(filenames);
}
try
{
foreach (string f in Directory.GetFiles(dirName))
{
if (f.ToLower().EndsWith(".xls") || f.ToLower().EndsWith(".xlsx"))
{
_fileNames.Add(f);
}
}
dirNames = Directory.GetDirectories(dirName).ToList();
foreach (string d in dirNames)
{
GetExcelFiles(d, _fileNames);
}
}
catch (Exception ex)
{
//Bam
}
return _fileNames;
}
Directory.GetFiles("C:\\", "*.*", SearchOption.AllDirectories)
Cómo evitar el error si el usuario de inicio de sesión no tiene acceso en algunas de las carpetas. –
@Romil No creo que este fragmento de código intente indicar la funcionalidad completa, solo la funcionalidad sin procesar que el OP estaba buscando. Gracias por compartir, Pescuma! –
@kayleeFrye_onDeck, puse solo una preocupación en caso de que haya un problema para cualquiera de la carpeta al obtener archivos. Debido a esta preocupación, implementamos nuestra función recursiva personalizada. –
Listado de archivos y carpetas para modelar, implementación personalizada.
Esto crea una lista completa de todos los archivos y carpetas a partir de su directorio de inicio.
public class DirOrFileModel
{
#region Private Members
private string _name;
private string _location;
private EntryType _entryType;
#endregion
#region Bindings
public string Name
{
get { return _name; }
set
{
if (value == _name) return;
_name = value;
}
}
public string Location
{
get { return _location; }
set
{
if (value == _location) return;
_location = value;
}
}
public EntryType EntryType
{
get { return _entryType; }
set
{
if (value == _entryType) return;
_entryType = value;
}
}
public ObservableCollection<DirOrFileModel> Entries { get; set; }
#endregion
#region Constructor
public DirOrFileModel()
{
Entries = new ObservableCollection<DirOrFileModel>();
}
#endregion
}
public enum EntryType
{
Directory = 0,
File = 1
}
Método:
static DirOrFileModel DirSearch(DirOrFileModel startDir)
{
var currentDir = startDir;
try
{
foreach (string d in Directory.GetDirectories(currentDir.Location))
{
var newDir = new DirOrFileModel
{
EntryType = EntryType.Directory,
Location = d,
Name = Path.GetFileName(d)
};
currentDir.Entries.Add(newDir);
DirSearch(newDir);
}
foreach (string f in Directory.GetFiles(currentDir.Location))
{
var newFile = new DirOrFileModel
{
EntryType = EntryType.File,
Location = f,
Name = Path.GetFileNameWithoutExtension(f)
};
currentDir.Entries.Add(newFile);
}
}
catch (Exception excpt)
{
Console.WriteLine(excpt.Message);
}
return startDir;
}
Uso:
var dir = new DirOrFileModel
{
Name = "C",
Location = @"C:\",
EntryType = EntryType.Directory
};
dir = DirSearch(dir);
static void Main(string[] args)
{
string[] array1 = Directory.GetFiles(@"D:\");
string[] array2 = System.IO.Directory.GetDirectories(@"D:\");
Console.WriteLine("--- Files: ---");
foreach (string name in array1)
{
Console.WriteLine(name);
}
foreach (string name in array2)
{
Console.WriteLine(name);
}
Console.ReadLine();
}
IEnumerable<string> GetFilesFromDir(string dir) =>
Directory.EnumerateFiles(dir).Concat(
Directory.EnumerateDirectories(dir)
.SelectMany(subdir => GetFilesFromDir(subdir)));
Una solución simple y limpio
/// <summary>
/// Scans a folder and all of its subfolders recursively, and updates the List of files
/// </summary>
/// <param name="sFullPath">Full path of the folder</param>
/// <param name="files">The list, where the output is expected</param>
internal static void EnumerateFiles(string sFullPath, List<FileInfo> fileInfoList)
{
try
{
DirectoryInfo di = new DirectoryInfo(sFullPath);
FileInfo[] files = di.GetFiles();
foreach (FileInfo file in files)
fileInfoList.Add(file);
//Scan recursively
DirectoryInfo[] dirs = di.GetDirectories();
if (dirs == null || dirs.Length < 1)
return;
foreach (DirectoryInfo dir in dirs)
EnumerateFiles(dir.FullName, fileInfoList);
}
catch (Exception ex)
{
Logger.Write("Exception in Helper.EnumerateFiles", ex);
}
}
}
Estás haciendo manualmente lo que DirectoryInfo.GetFiles() hará por ti de la caja: simplemente usa la sobrecarga con SearchOption.AllDirectories y se volverá a generar por sí solo. Entonces esa es una * solución * complicada. – philw
private void GetFiles(DirectoryInfo dir, ref List<FileInfo> files)
{
try
{
files.AddRange(dir.GetFiles());
DirectoryInfo[] dirs = dir.GetDirectories();
foreach (var d in dirs)
{
GetFiles(d, ref files);
}
}
catch (Exception e)
{
}
}
¿Por qué el parámetro 'files' es' ref'? No hay necesidad. –
solución a corto y simple
string dir = @"D:\PATH";
DateTime from_date = DateTime.Now.Date;
DateTime to_date = DateTime.Now.Date.AddHours(23);
var files = Directory.EnumerateFiles(dir, "*.*",SearchOption.AllDirectories).Select(i=>new FileInfo(i))
.Where(file=>file.LastWriteTime >= from_date && file.LastWriteTime <= to_date);
foreach(var fl in files)
Console.WriteLine(fl.FullName);
Yo prefiero usar DirectoryInfo porque puedo conseguir, no sólo cadenas de FileInfo.
string baseFolder = @"C:\temp";
DirectoryInfo di = new DirectoryInfo(baseFolder);
string searchPattern = "*.xml";
ICollection<FileInfo> matchingFileInfos = di.GetFiles(searchPattern, SearchOption.AllDirectories)
.Select(x => x)
.ToList();
Lo hago en caso de que en el futuro necesite un futuro filtrado ... en función de las propiedades de FileInfo.
string baseFolder = @"C:\temp";
DirectoryInfo di = new DirectoryInfo(baseFolder);
string searchPattern = "*.xml";
ICollection<FileInfo> matchingFileInfos = di.GetFiles(searchPattern, SearchOption.AllDirectories)
.Where(x => x.LastWriteTimeUtc < DateTimeOffset.Now)
.Select(x => x)
.ToList();
También puedo recurrir a las cadenas si es necesario. (Y todavía lo soy prueba de futuro para los filtros/cláusula-where cosas.
string baseFolder = @"C:\temp";
DirectoryInfo di = new DirectoryInfo(baseFolder);
string searchPattern = "*.xml";
ICollection<string> matchingFileNames = di.GetFiles(searchPattern, SearchOption.AllDirectories)
.Select(x => x.FullName)
.ToList();
Tenga en cuenta que "" es un patrón de búsqueda válida si quieres Filer por extensión.
- 1. Cómo recursivamente enumerar todos los archivos y directorios
- 2. Difiere un directorio recursivamente, Ignorando todos los archivos binarios:
- 3. windows .bat file cómo enumerar recursivamente todos los archivos de tipo * .mp3
- 4. lista LINUX recursivamente todos los archivos en un directorio incluyendo los archivos en directorios de enlaces simbólicos
- 5. ¿Cómo enumerar todos los archivos modificados en un volumen oculto?
- 6. iterar recursivamente sobre todos los archivos en un directorio y sus subdirectorios en Qt
- 7. Obtener rutas absolutas de todos los archivos en un directorio
- 8. ¿Cómo puedo enumerar todos los archivos en un directorio ordenados alfabéticamente usando PHP?
- 9. ¿Cómo puedo enumerar todos los archivos en un directorio usando Perl?
- 10. ¿Cómo puedo encontrar todos los archivos * .js en el directorio recursivamente en Linux?
- 11. Hacer ejecutables todos los archivos PHP (recursivamente)
- 12. ¿Cómo crear recursivamente un directorio en Qt?
- 13. Listar todos los archivos y directorios en un directorio + subdirectorios
- 14. Imprimir recursivamente todos los archivos de Vim
- 15. Copie todos los archivos en el directorio
- 16. gmake compila todos los archivos en un directorio
- 17. ¿Cómo formatear todos los archivos bajo un directorio en emacs?
- 18. ¿Cómo recupero todos los nombres de archivos en un directorio?
- 19. Cómo obtener archivos en un directorio, incluidos todos los subdirectorios
- 20. ¿Cómo obtener todos los archivos en un directorio?
- 21. ¿Cómo enumerar los contenidos del directorio con FTP en C#?
- 22. Comando Bash para enumerar recursivamente archivos, pero clasificándolos por clasificación
- 23. Listar los archivos en un directorio y todos los subdirectorios
- 24. Cómo eliminar archivos recursivamente
- 25. ¿Qué se expande a todos los archivos en el directorio actual recursivamente?
- 26. Java: ¿cómo obtener todos los subdires recursivamente?
- 27. git: ¿Cómo puedo agregar recursivamente todos los archivos en un subárbol de directorio que coinciden con un patrón global?
- 28. Ejecutar todos los archivos Python en un directorio
- 29. Unir todos los archivos en un directorio, con un separador
- 30. Buscar todos los archivos CSV en un directorio usando Python
¿Dónde quiere poblar ? if tree ... aquí está el ejemplo http://www.dreamincode.net/code/snippet2591.htm –
Es posible que desee consultar [esta pregunta] (http://stackoverflow.com/questions/907307/ directory-structure-within-treeview-vb /) donde he presentado un ejemplo de código que usa la recursividad para representar una estructura de directorios en un TreeView. La lógica debería ser la misma en la mayoría de los casos. – Cerebrus
string [] filenames = Dire ctory.GetFiles (ruta, "*", SearchOption.AllDirectories) – Bruce