2012-09-08 292 views
50

我想列出目錄中包含的每個文件和目錄以及該目錄的子目錄。如果我選擇C:\作爲目錄,程序將獲取它有權訪問的硬盤驅動器上的每個文件和文件夾的名稱。列出目錄+子目錄中的所有文件和目錄

名單看​​起來像

 
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

瀏覽System.IO命名空間爲[等級](http://msdn.microsoft.com/en-us/library/wa70yfe2(V = vs.100))和[methods](http://msdn.microsoft.com/en-us/library/dd383459(v = vs.100))可能對你有幫助。 – Lucero

+0

查看[這個問題](http://stackoverflow.com/q/1651869/335858),並放下他匹配模式的部分。 – dasblinkenlight

+0

可能重複的[如何遞歸列出C#中的目錄中的所有文件?](http://stackoverflow.com/questions/929276/how-to-recursively-list-all-the-files-in-a- directory-in-c) – JoshRivers

回答

13

使用GetDirectoriesGetFiles方法來獲取文件夾和文件。

使用SearchOptionAllDirectories也可以獲取子文件夾中的文件夾和文件。

+0

使用[子字符串](http://msdn.microsoft.com/en-us/library/hxthx5h6.aspx)來切斷名稱的左側部分。 :) – Lucero

+0

@Lucero你如何以及爲什麼要這樣做? 'Path'提供更可靠的方法。 – Gusdor

+0

@Gusdor隨意使用'Path'來建議一個更合適的方法來去除固定的路徑左邊部分,例如在給出的例子中是'C:\'。 – Lucero

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

其中*.*是模式匹配的文件

如果該目錄還需要可以是這樣的:

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

不會真的工作......'Lsit <>'class? GetFiles返回什麼?那麼還請求了目錄名稱呢? – Lucero

+1

'GetFiles'方法返回一個字符串數組。 – Guffa

+0

actualy ...你是對的... 2天前我正在學習Qt abaout並被誤認爲有點 –

3

恐怕,該GetFiles方法返回文件,但並不是名單目錄。問題中的列表提示我結果應該包含文件夾。如果你想要更多的定製列表,你可以嘗試遞歸調用GetFilesGetDirectories。試試這個:

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

提示:如果您需要檢查任何特定的屬性,則可以使用FileInfoDirectoryInfo類。

17

Directory.GetFileSystemEntries存在於.NET 4.0+中,並返回文件和目錄。說它像這樣:

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

注意,它不會嘗試列出您沒有訪問權限(UnauthorizedAccessException)子目錄的內容應付,但它可以爲您的需要是足夠的。

+2

這是迄今爲止最好的答案。它將所有文件和文件夾放在一行代碼中,而其他所有代碼都不做。 –

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

你的答案並沒有增加任何新的東西,現有的最高票數的答案。 –

+1

這也是錯誤的,因爲這不會返回任何目錄(如指定的問題),只有實際的文件。 –

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

如果你可以添加一些關於代碼的解釋,它會改善你的答案。 – Alex

0

如果您沒有訪問該目錄樹中的子文件夾,Directory.GetFiles停止並拋出導致接收的String []在一個空值異常。

這裏,看到這個答案 https://stackoverflow.com/a/38959208/6310707

它管理循環中的異常,並保持下去,直到整個文件夾的工作遍歷。

0

以下示例最快(未並行化)方式列表文件和目錄樹中的子文件夾處理異常。使用Directory.EnumerateDirectories使用SearchOption.AllDirectories枚舉所有目錄會更快,但如果遇到UnauthorizedAccessException或PathTooLongException,則此方法將失敗。

使用通用堆棧集合類型,它是後進先出(LIFO)堆棧,不使用遞歸。從https://msdn.microsoft.com/en-us/library/bb513869.aspx,允許您枚舉所有子目錄和文件並有效處理這些例外。

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

對於龐大的數字文件和目錄,使用***任務***? –

+0

https://msdn.microsoft.com/zh-cn/library/ff477033(v=vs.110).aspx是上述解決方案的並行線程版本,它使用堆棧集合並且更快。 – Markus

0

邏輯和有序的方式:

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

你能提供一個解釋或在線評論,你的代碼做什麼? – MarthyM

+0

當然,完成它,但它應該是自我解釋,它是一個簡單的循環遞歸通過所有的目錄和文件 – Sascha

0

我使用下面的代碼與具有2個按鈕,一個用於出口,另一個啓動的形式。文件夾瀏覽器對話框和保存文件對話框。代碼是下面列出和工作我的系統Windows10(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); 
      } 
     } 
    } 
} 
相關問題