2012-09-08 6 views
50

Desidero elencare tutti i file e le directory contenuti in una directory e sottodirectory di tale directory. Se avessi scelto C: \ come directory, il programma avrebbe ottenuto ogni nome di ogni file e cartella sul disco rigido a cui aveva accesso.Elenca tutti i file e le directory in una directory + sottodirectory

Un elenco potrebbe essere simile

 
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

sfogliare lo spazio dei nomi System.IO per [classi] (http://msdn.microsoft.com/en-us/library/wa70yfe2 (v = vs.100)) e [metodi] (http://msdn.microsoft.com/en-us/library/dd383459 (v = vs.100)) che potrebbero aiutarti. – Lucero

+0

Dai un'occhiata a [questa domanda] (http://stackoverflow.com/q/1651869/335858) e rilascia la parte in cui corrisponde a un modello. – dasblinkenlight

+0

possibile duplicato di [Come elencare in modo ricorsivo tutti i file in una directory in C#?] (Http://stackoverflow.com/questions/929276/how-to-recursively-list-all-the-files-in-a- directory-in-c) – JoshRivers

risposta

13

Utilizzare le GetDirectories e GetFiles metodi per ottenere le cartelle ei file.

Utilizzare il SearchOptionAllDirectories per ottenere le cartelle ei file nelle sottocartelle anche.

+0

Utilizzare [Sottostringa] (http://msdn.microsoft.com/en-us/library/hxthx5h6.aspx) per tagliare la parte sinistra del nome. :) – Lucero

+0

@Lucero Come e perché vorresti farlo? 'Path' offre metodi più affidabili. – Gusdor

+0

@Gusdor Sentiti libero di suggerire un modo più adatto usando il 'Percorso' per rimuovere una parte sinistra fissa del percorso, ad es. 'C: \' nell'esempio fornito. – Lucero

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

dove *.* è modello per abbinare i file

se la directory è necessaria anche si può andare in questo modo:

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

Non funziona davvero ... classe 'Lsit <>'? Cosa restituisce GetFiles? E i nomi delle directory che sono stati anche richiesti? – Lucero

+1

Il metodo 'GetFiles' restituisce una matrice di stringhe. – Guffa

+0

actualy ... hai ragione ... Sto imparando Qt abaout 2 giorni fa e ho sbagliato un po ' –

3

temo, il metodo GetFiles restituisce l'elenco dei file, ma non le directory. L'elenco nella domanda mi suggerisce che il risultato dovrebbe includere anche le cartelle. Se si desidera un elenco più personalizzato, è possibile provare a chiamare in modo ricorsivo chiamando GetFiles e GetDirectories. Prova questo:

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); 
} 

Suggerimento: è possibile utilizzare FileInfo e DirectoryInfo classi, se avete bisogno di controllare qualsiasi attributo specifico.

17

Directory.GetFileSystemEntries esiste in .NET 4.0+ e restituisce sia i file che le directory. Chiamatela in questo modo:

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

Nota che non farà fronte con i tentativi di elencare il contenuto della sottodirectory che non si ha accesso (UnauthorizedAccessException), ma può essere sufficiente per le vostre esigenze.

+2

Questa è di gran lunga la migliore risposta qui. Ottiene tutti i file e le cartelle in una riga di codice, che nessuno degli altri fa. –

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

La tua risposta non aggiunge nulla di nuovo a una risposta già votata dall'alto. –

+1

È anche sbagliato, in quanto ciò non restituisce alcuna directory (come la domanda specificata), solo i file effettivi. –

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

Migliorerebbe la tua risposta se puoi aggiungere una piccola spiegazione di cosa fa il codice. – Alex

0

Se non si ha accesso a una sottocartella all'interno della struttura di directory, Directory.GetFiles si ferma e getta l'eccezione risultante in un valore nullo nella stringa di ricezione [].

Qui, si veda questa risposta https://stackoverflow.com/a/38959208/6310707

Gestisce l'eccezione all'interno del ciclo e continuare a lavorare fino l'intera cartella è attraversato.

0

Nell'esempio seguente, il più veloce (non in parallelo) elenca file e sottocartelle in una struttura di directory che gestisce le eccezioni. Sarebbe più rapido utilizzare Directory.EnumerateDirectories utilizzando SearchOption.AllDirectories per enumerare tutte le directory, ma questo metodo non riuscirà se viene rilevato un oggetto UnauthorizedAccessException o PathTooLongException.

Utilizza il tipo di raccolta Stack generica, che è uno stack Last in First Out (LIFO) e non utilizza la ricorsione. Da https://msdn.microsoft.com/en-us/library/bb513869.aspx, consente di enumerare tutte le sottodirectory e i file e gestire efficacemente tali eccezioni.

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

Utilizzare *** Tasks *** per grandi file e directory di numeri enormi? –

+0

https://msdn.microsoft.com/en-us/library/ff477033(v=vs.110).aspx è la versione Parallel Threading della soluzione di cui sopra utilizzando una raccolta stack e più veloce. – Markus

0

modo logico e ordinato:

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

Potresti fornire una spiegazione o commenti in linea, che cosa fa il tuo codice? – MarthyM

+0

ovviamente, fatto, ma dovrebbe essere auto esplicativo, è una semplice ricorsione in loop attraverso tutte le directory e file – Sascha

0

utilizza la seguente codice con un modulo che ha 2 pulsanti, uno per l'uscita e l'altra per iniziare. Una finestra di dialogo del browser delle cartelle e una finestra di dialogo per il salvataggio dei file. Codice è elencato di seguito e lavora sul mio 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); 
      } 
     } 
    } 
} 
Problemi correlati