2012-09-08 27 views
50

Quiero enumerar todos los archivos y directorios contenidos en un directorio y subdirectorios de ese directorio. Si elegí C: \ como el directorio, el programa obtendría cada nombre de cada archivo y carpeta en el disco duro al que tenía acceso.Listar todos los archivos y directorios en un directorio + subdirectorios

Una lista podría ser como

 
fd\1.txt 
fd\2.txt 
fd\a\ 
fd\b\ 
fd\a\1.txt 
fd\a\2.txt 
fd\a\a\ 
fd\a\b\ 
fd\b\1.txt 
fd\b\2.txt 
fd\b\a 
fd\b\b 
fd\a\a\1.txt 
fd\a\a\a\ 
fd\a\b\1.txt 
fd\a\b\a 
fd\b\a\1.txt 
fd\b\a\a\ 
fd\b\b\1.txt 
fd\b\b\a 
+0

Explorar el espacio de nombres System.IO para [clases] (http://msdn.microsoft.com/en-us/library/wa70yfe2 (v = vs.100)) y [métodos] (http://msdn.microsoft.com/en-us/library/dd383459 (v = vs.100)) que podrían ayudarlo. – Lucero

+0

Consulte [esta pregunta] (http://stackoverflow.com/q/1651869/335858), y coloque la parte donde coincide con un patrón. – dasblinkenlight

+0

posible duplicado de [Cómo recursivamente enumerar todos los archivos en un directorio en C#?] (Http://stackoverflow.com/questions/929276/how-to-recursively-list-all-the-files-in-a- directory-in-c) – JoshRivers

Respuesta

13

utilizar los métodos y GetDirectoriesGetFiles para obtener las carpetas y archivos.

Utilice SearchOptionAllDirectories para obtener las carpetas y archivos en las subcarpetas también.

+0

Utilice [Substring] (http://msdn.microsoft.com/en-us/library/hxthx5h6.aspx) para cortar la parte izquierda del nombre. :) – Lucero

+0

@Lucero ¿Cómo y por qué harías eso? 'Path' ofrece métodos más confiables. – Gusdor

+0

@Gusdor Siéntase libre de sugerir una forma más adecuada mediante la 'Ruta' para eliminar una parte fija de la ruta, por ejemplo, 'C: \' en el ejemplo dado. – Lucero

111
string[] allfiles = System.IO.Directory.GetFiles("path/to/dir", "*.*", System.IO.SearchOption.AllDirectories); 

donde *.* es el patrón para que coincida con los archivos

Si el directorio también se necesita se puede ir así:

foreach (var file in allfiles){ 
    FileInfo info = new FileInfo(file); 
// Do something with the Folder or just add them to a list via nameoflist.add(); 
} 
+0

Realmente no funcionará ... 'Lsit <>' clase? ¿Qué devuelve GetFiles? ¿Y los nombres de directorio que también fueron solicitados? – Lucero

+1

El método 'GetFiles' devuelve una matriz de cadenas. – Guffa

+0

actualmente ... tienes razón ... Estoy aprendiendo Qt abaout hace 2 días y me equivoqué un poco –

3

me temo, el método GetFiles lista de archivos, pero no devuelve los directorios. La lista en la pregunta me indica que el resultado también debe incluir las carpetas. Si desea una lista más personalizada, puede intentar llamar GetFiles y GetDirectories recursivamente. Prueba esto:

List<string> AllFiles = new List<string>(); 
void ParsePath(string path) 
{ 
    string[] SubDirs = Directory.GetDirectories(path); 
    AllFiles.AddRange(SubDirs); 
    AllFiles.AddRange(Directory.GetFiles(path)); 
    foreach (string subdir in SubDirs) 
     ParsePath(subdir); 
} 

Consejo: Puede utilizar FileInfo y DirectoryInfo clases si es necesario comprobar cualquier atributo específico.

17

Directory.GetFileSystemEntries existe en .NET 4.0+ y devuelve ambos archivos y directorios. Llamarlo así:

string[] entries = Directory.GetFileSystemEntries(
    path, "*", SearchOption.AllDirectories); 

Tenga en cuenta que no va a hacer frente a los intentos de mostrar el contenido de los subdirectorios que usted no tiene acceso a (UnauthorizedAccessException), pero puede ser suficiente para sus necesidades.

+2

Esta es, de lejos, la mejor respuesta aquí. Obtiene todos los archivos y carpetas en una línea de código, que ninguno de los otros hace. –

-1
using System.IO; 
using System.Text; 
string[] filePaths = Directory.GetFiles(@"path", "*.*", SearchOption.AllDirectories); 
+0

Su respuesta no agrega nada nuevo a una respuesta más votado ya existente. –

+1

También es incorrecto, ya que esto no devuelve ningún directorio (como la pregunta especificada), solo los archivos reales. –

3
public static void DirectorySearch(string dir) 
    { 
     try 
     { 
      foreach (string f in Directory.GetFiles(dir)) 
      { 
       Console.WriteLine(Path.GetFileName(f)); 
      } 
      foreach (string d in Directory.GetDirectories(dir)) 
      { 
       Console.WriteLine(Path.GetFileName(d)); 
       DirectorySearch(d); 
      } 

     } 
     catch (System.Exception ex) 
     { 
      Console.WriteLine(ex.Message); 
     } 
    } 
+1

Mejorará su respuesta si puede agregar una pequeña explicación de lo que hace el código. – Alex

0

Si usted no tiene acceso a una subcarpeta dentro del árbol de directorios, Directory.GetFiles se detiene y se inicia la excepción que resulta en un valor nulo en la cadena de recepción [].

Aquí, ver esta respuesta https://stackoverflow.com/a/38959208/6310707

Gestiona la excepción dentro del bucle y seguir trabajando hasta el toda la carpeta está atravesado.

0

El siguiente ejemplo es más rápido (no en paralelo) lista de rutas de archivos y subcarpetas en un árbol de directorios que maneja excepciones. Sería más rápido usar Directory.EnumerateDirectories usando SearchOption.AllDirectories para enumerar todos los directorios, pero este método fallará si golpea una excepción de acceso no autorizada o PathTooLongException.

Utiliza el tipo de colección Stack genérica, que es una pila de último en entrar primero en salir (LIFO) y no usa recursividad. Desde https://msdn.microsoft.com/en-us/library/bb513869.aspx, le permite enumerar todos los subdirectorios y archivos y tratar eficazmente esas excepciones.

public class StackBasedIteration 
{ 
    static void Main(string[] args) 
    { 
     // Specify the starting folder on the command line, or in 
     // Visual Studio in the Project > Properties > Debug pane. 
     TraverseTree(args[0]); 

     Console.WriteLine("Press any key"); 
     Console.ReadKey(); 
    } 

    public static void TraverseTree(string root) 
    { 
     // Data structure to hold names of subfolders to be 
     // examined for files. 
     Stack<string> dirs = new Stack<string>(20); 

     if (!System.IO.Directory.Exists(root)) 
     { 
      throw new ArgumentException(); 
     } 
     dirs.Push(root); 

     while (dirs.Count > 0) 
     { 
      string currentDir = dirs.Pop(); 
      string[] subDirs; 
      try 
      { 
       subDirs = System.IO.Directory.EnumerateDirectories(currentDir); //TopDirectoryOnly 
      } 
      // An UnauthorizedAccessException exception will be thrown if we do not have 
      // discovery permission on a folder or file. It may or may not be acceptable 
      // to ignore the exception and continue enumerating the remaining files and 
      // folders. It is also possible (but unlikely) that a DirectoryNotFound exception 
      // will be raised. This will happen if currentDir has been deleted by 
      // another application or thread after our call to Directory.Exists. The 
      // choice of which exceptions to catch depends entirely on the specific task 
      // you are intending to perform and also on how much you know with certainty 
      // about the systems on which this code will run. 
      catch (UnauthorizedAccessException e) 
      {      
       Console.WriteLine(e.Message); 
       continue; 
      } 
      catch (System.IO.DirectoryNotFoundException e) 
      { 
       Console.WriteLine(e.Message); 
       continue; 
      } 

      string[] files = null; 
      try 
      { 
       files = System.IO.Directory.EnumerateFiles(currentDir); 
      } 

      catch (UnauthorizedAccessException e) 
      { 

       Console.WriteLine(e.Message); 
       continue; 
      } 

      catch (System.IO.DirectoryNotFoundException e) 
      { 
       Console.WriteLine(e.Message); 
       continue; 
      } 
      // Perform the required action on each file here. 
      // Modify this block to perform your required task. 
      foreach (string file in files) 
      { 
       try 
       { 
        // Perform whatever action is required in your scenario. 
        System.IO.FileInfo fi = new System.IO.FileInfo(file); 
        Console.WriteLine("{0}: {1}, {2}", fi.Name, fi.Length, fi.CreationTime); 
       } 
       catch (System.IO.FileNotFoundException e) 
       { 
        // If file was deleted by a separate application 
        // or thread since the call to TraverseTree() 
        // then just continue. 
        Console.WriteLine(e.Message); 
        continue; 
       } 
       catch (UnauthorizedAccessException e) 
       {      
        Console.WriteLine(e.Message); 
        continue; 
       } 
      } 

      // Push the subdirectories onto the stack for traversal. 
      // This could also be done before handing the files. 
      foreach (string str in subDirs) 
       dirs.Push(str); 
     } 
    } 
} 
+0

Usando *** Tasks *** para archivos y directorios de gran cantidad de números enormes –

+0

https://msdn.microsoft.com/en-us/library/ff477033(v=vs.110).aspx es la versión de enhebrado paralelo de la solución anterior que utiliza una colección de pila y es más rápida. – Markus

0

la manera lógica y ordenada:

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Reflection; 

namespace DirLister 
{ 
class Program 
{ 
    public static void Main(string[] args) 
    { 
     //with reflection I get the directory from where this program is running, thus listing all files from there and all subdirectories 
     string[] st = FindFileDir(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)); 
     using (StreamWriter sw = new StreamWriter("listing.txt", false)) 
     { 
      foreach(string s in st) 
      { 
       //I write what I found in a text file 
       sw.WriteLine(s); 
      } 
     } 
    } 

    private static string[] FindFileDir(string beginpath) 
    { 
     List<string> findlist = new List<string>(); 

     /* I begin a recursion, following the order: 
     * - Insert all the files in the current directory with the recursion 
     * - Insert all subdirectories in the list and rebegin the recursion from there until the end 
     */ 
     RecurseFind(beginpath, findlist); 

     return findlist.ToArray(); 
    } 

    private static void RecurseFind(string path, List<string> list) 
    { 
     string[] fl = Directory.GetFiles(path); 
     string[] dl = Directory.GetDirectories(path); 
     if (fl.Length>0 || dl.Length>0) 
     { 
      //I begin with the files, and store all of them in the list 
      foreach(string s in fl) 
       list.Add(s); 
      //I then add the directory and recurse that directory, the process will repeat until there are no more files and directories to recurse 
      foreach(string s in dl) 
      { 
       list.Add(s); 
       RecurseFind(s, list); 
      } 
     } 
    } 
} 
} 
+0

¿Podría proporcionar una explicación o comentarios en línea, qué hace su código? – MarthyM

+0

por supuesto, lo hizo, pero debe ser auto explicativo, es una recursión de bucle simple a través de todos los directorios y archivos – Sascha

0

uso el siguiente código con un formulario que tiene 2 botones, uno para la salida y el otro para empezar. Un diálogo de buscador de carpeta y un diálogo de guardar archivo. Código se lista a continuación y funciona en mi sistema Windows 10 (64):

using System; 
using System.IO; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 

namespace Directory_List 
{ 

    public partial class Form1 : Form 
    { 
     public string MyPath = ""; 
     public string MyFileName = ""; 
     public string str = ""; 

     public Form1() 
     { 
      InitializeComponent(); 
     }  
     private void cmdQuit_Click(object sender, EventArgs e) 
     { 
      Application.Exit(); 
     }  
     private void cmdGetDirectory_Click(object sender, EventArgs e) 
     { 
      folderBrowserDialog1.ShowDialog(); 
      MyPath = folderBrowserDialog1.SelectedPath;  
      saveFileDialog1.ShowDialog(); 
      MyFileName = saveFileDialog1.FileName;  
      str = "Folder = " + MyPath + "\r\n\r\n\r\n";  
      DirectorySearch(MyPath);  
      var result = MessageBox.Show("Directory saved to Disk!", "", MessageBoxButtons.OK); 
       Application.Exit();  
     }  
     public void DirectorySearch(string dir) 
     { 
       try 
      { 
       foreach (string f in Directory.GetFiles(dir)) 
       { 
        str = str + dir + "\\" + (Path.GetFileName(f)) + "\r\n"; 
       }  
       foreach (string d in Directory.GetDirectories(dir, "*")) 
       { 

        DirectorySearch(d); 
       } 
         System.IO.File.WriteAllText(MyFileName, str); 

      } 
      catch (System.Exception ex) 
      { 
       Console.WriteLine(ex.Message); 
      } 
     } 
    } 
} 
Cuestiones relacionadas