2012-09-08 65 views
50

Tôi muốn liệt kê mọi tệp và thư mục chứa trong thư mục và thư mục con của thư mục đó. Nếu tôi chọn C: \ làm thư mục, chương trình sẽ lấy mọi tên của mọi tệp và thư mục trên ổ đĩa cứng mà nó có quyền truy cập.Liệt kê tất cả các tệp và thư mục trong thư mục + thư mục con

Một danh sách có thể trông như

 
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

Duyệt không gian tên System.IO cho [lớp] (http://msdn.microsoft.com/en-us/library/wa70yfe2 (v = vs.100)) và [phương pháp] (http://msdn.microsoft.com/en-us/library/dd383459 (v = vs.100)) có thể giúp bạn. – Lucero

+0

Kiểm tra [câu hỏi này] (http://stackoverflow.com/q/1651869/335858) và thả phần mà anh ấy khớp với mẫu. – dasblinkenlight

+0

bản sao có thể có của [Cách đệ quy liệt kê tất cả các tệp trong một thư mục trong C#?] (Http://stackoverflow.com/questions/929276/how-to-recursively-list-all-the-files-in-a- directory-in-c) – JoshRivers

Trả lời

13

Sử dụng các phương pháp GetDirectoriesGetFiles để có được các thư mục và tập tin.

Sử dụng SearchOptionAllDirectories để nhận thư mục và tệp trong thư mục con.

+0

Sử dụng [Chuỗi con] (http://msdn.microsoft.com/en-us/library/hxthx5h6.aspx) để cắt phần bên trái của tên. :) – Lucero

+0

@Lucero Làm thế nào và tại sao bạn sẽ làm điều đó? 'Path' cung cấp các phương thức đáng tin cậy hơn. – Gusdor

+0

@Gusdor Vui lòng đề xuất cách phù hợp hơn bằng cách sử dụng 'Đường dẫn' để xóa phần cố định bên trái của đường dẫn, ví dụ: 'C: \' trong ví dụ đã cho. – Lucero

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

nơi *.* là mô hình để phù hợp với file

Nếu danh mục cũng cần thiết bạn có thể đi như thế này:

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

Sẽ không thực sự hoạt động ... 'Lsit <>' class? GetFiles trả về những gì? Và những gì về tên thư mục cũng được yêu cầu? – Lucero

+1

Phương thức 'GetFiles' trả về một mảng chuỗi. – Guffa

+0

actualy ... bạn đang phải ... Tôi đang học cách Qt abaout 2 ngày trước và bị nhầm lẫn một chút –

3

tôi sợ, phương pháp GetFiles trả về danh sách các tập tin mà không các thư mục. Danh sách trong câu hỏi sẽ nhắc tôi rằng kết quả cũng nên bao gồm các thư mục. Nếu bạn muốn có thêm danh sách tùy chỉnh, bạn có thể thử gọi GetFilesGetDirectories đệ quy. Hãy thử điều này:

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

Mẹo: Bạn có thể sử dụng FileInfoDirectoryInfo lớp nếu bạn cần phải kiểm tra bất kỳ thuộc tính cụ thể.

17

Directory.GetFileSystemEntries tồn tại trong .NET 4.0+ và trả về cả tệp và thư mục. Gọi nó như vậy:

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

Lưu ý rằng nó sẽ không đối phó với những nỗ lực để liệt kê nội dung của thư mục con mà bạn không có quyền truy cập vào (UnauthorizedAccessException), nhưng nó có thể là đủ cho nhu cầu của bạn.

+2

Đây là câu trả lời hay nhất ở đây. Nó nhận tất cả các tập tin và thư mục trong một dòng mã, mà không ai trong số những người khác làm. –

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

Câu trả lời của bạn không thêm bất kỳ điều gì mới vào câu trả lời được bình chọn hàng đầu hiện có. –

+1

Nó cũng sai, vì điều này không trả về bất kỳ thư mục nào (như câu hỏi được chỉ định), chỉ các tệp thực tế. –

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

Nó sẽ cải thiện câu trả lời của bạn nếu bạn có thể thêm một chút giải thích về những gì các mã nào. – Alex

0

Nếu bạn không có quyền truy cập vào một thư mục con bên trong cây thư mục, Directory.GetFiles dừng lại và ném ngoại lệ dẫn đến một giá trị null trong chuỗi nhận [].

Ở đây, nhìn thấy câu trả lời này https://stackoverflow.com/a/38959208/6310707

Nó quản lý các ngoại lệ bên trong vòng lặp và tiếp tục làm việc cho đến khi toàn bộ thư mục được truy cập.

0

Ví dụ sau nhanh nhất (không song song) cách liệt kê các tệp và thư mục con trong thư mục xử lý ngoại lệ của cây thư mục. Sẽ nhanh hơn khi sử dụng Directory.EnumerateDirectories bằng cách sử dụng SearchOption.AllDirectories để liệt kê tất cả các thư mục, nhưng phương thức này sẽ thất bại nếu truy cập UnauthorizedAccessException hoặc PathTooLongException.

Sử dụng loại bộ sưu tập Ngăn xếp chung, đây là loại ngăn xếp cuối cùng trong lần đầu tiên (LIFO) và không sử dụng đệ quy. Từ https://msdn.microsoft.com/en-us/library/bb513869.aspx, cho phép bạn liệt kê tất cả các thư mục con và tệp và xử lý hiệu quả với những ngoại lệ đó.

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

Sử dụng các tác vụ *** cho các tệp và thư mục số lớn lớn? –

+0

https://msdn.microsoft.com/en-us/library/ff477033(v=vs.110).aspx là phiên bản Song song luồng của giải pháp trên bằng cách sử dụng bộ sưu tập ngăn xếp và nhanh hơn. – Markus

0

cách logic và ra lệnh:

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

Bạn có thể vui lòng cung cấp giải thích hoặc nhận xét nội dòng, mã của bạn có làm gì không? – MarthyM

+0

tất nhiên, thực hiện nó, nhưng nó phải được tự giải thích, đó là một đệ quy lặp đơn giản thông qua tất cả các thư mục và tập tin – Sascha

0

tôi sử dụng đoạn mã sau với một hình thức có 2 nút, một cho xuất cảnh, người kia để bắt đầu. Hộp thoại trình duyệt thư mục và hộp thoại lưu tệp. Mã được liệt kê bên dưới và hoạt động trên hệ thống của tôi 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); 
      } 
     } 
    } 
} 
Các vấn đề liên quan