2012-03-22 52 views
28

Tôi có đoạn mã sau đây để tìm kiếm đệ quy các tập tin thông qua một thư mục, trả về danh sách tất cả các tệp xml cho tôi. Tất cả hoạt động tốt, ngoại trừ các tệp xml trong thư mục gốc không được bao gồm trong danh sách.Tìm kiếm tập tin trong thư mục đệ quy

Tôi hiểu tại sao, vì điều đầu tiên nó thực hiện là lấy các thư mục trong thư mục gốc, sau đó nhận các tệp, do đó thiếu lệnh GetFiles() trên thư mục gốc. Tôi đã thử bao gồm cả GetFiles() gọi trước khi foreach, nhưng kết quả không như tôi mong đợi.

public static ArrayList DirSearch(string sDir) 
{ 
    try 
    { 
     foreach (string d in Directory.GetDirectories(sDir)) 
     { 
      foreach (string f in Directory.GetFiles(d, "*.xml")) 
      { 
       string extension = Path.GetExtension(f); 
       if (extension != null && (extension.Equals(".xml"))) 
       { 
       fileList.Add(f); 
       } 
      } 
      DirSearch(d); 
     } 
    } 
    catch (Exception ex) 
    { 
     Console.WriteLine(ex.Message); 
    } 
    return fileList; 
} 

cấu trúc thư mục của tôi là một cái gì đó như:

RootDirectory 
     test1.0.xml 
      test1.1.xml 
      test1.2.xml 
    2ndLevDir 
      test2.0.xml 
      test2.1.xml 
    3rdLevDir 
       test3.0.xml 
       test3.1.xml 

lợi nhuận Code:

test2.0.xml 
test2.1.xml 
test3.0.xml 
test3.1.xml 

Tôi muốn quay trở lại tất cả các file bao gồm:

test1.0.xml 
test1.1.xml 
test1.2.xml 

Không rất tốt câu với recursi trên. Bât cư thông tin được cung câp nao cung được la sự suât hiện tuyệt vơi.

+4

'Directory.EnumerateFiles (sDir, "* .xml", SearchOption.AllDirectories) ' –

Trả lời

67

Bạn có thể sử dụng this overload of Directory.GetFiles để tìm kiếm thư mục con cho bạn.

+18

' var filelist = new DirectoryInfo (sDir) .GetFiles (, SearchOption.AllDirectories "* xml.");' –

+1

Tôi có thể nhập nhiều mẫu tìm kiếm không? * .xml các loại tệp cộng với * .doc chẳng hạn ... – Paul

+1

Không xa như tôi có thể nói, nhưng cấu trúc thư mục có liên quan có thể được lưu trong bộ nhớ cache sau lần tìm kiếm đầu tiên. Thử nghiệm của bạn sẽ có thể kiểm tra xem nếu tốc độ là một mối quan tâm. –

3

Bạn nên có vòng lặp trên các tệp trước hoặc sau vòng lặp qua các thư mục, nhưng không được lồng vào bên trong nó như bạn đã làm.

foreach (string f in Directory.GetFiles(d, "*.xml")) 
{ 
    string extension = Path.GetExtension(f); 
    if (extension != null && (extension.Equals(".xml"))) 
    { 
     fileList.Add(f); 
    } 
} 

foreach (string d in Directory.GetDirectories(sDir)) 
{ 
    DirSearch(d); 
} 
3

Hãy thử các phương pháp sau đây:

public static IEnumerable<string> GetXMLFiles(string directory) 
{ 
    List<string> files = new List<string>(); 

    try 
    { 
     files.AddRange(Directory.GetFiles(directory, "*.xml", SearchOption.AllDirectories)); 
    } 
    catch (Exception ex) 
    { 
     Console.WriteLine(ex.Message); 
    } 

    return files; 
} 
1

Bạn sẽ w ant để di chuyển vòng lặp cho các tệp bên ngoài vòng lặp cho các thư mục. Ngoài ra, bạn sẽ cần phải vượt qua cấu trúc dữ liệu giữ tập hợp các tập tin cho mỗi cuộc gọi của phương pháp. Bằng cách đó tất cả các tập tin đi vào một danh sách duy nhất.

public static List<string> DirSearch(string sDir, List<string> files) 
{ 
    foreach (string f in Directory.GetFiles(sDir, "*.xml")) 
    { 
    string extension = Path.GetExtension(f); 
    if (extension != null && (extension.Equals(".xml"))) 
    { 
     files.Add(f); 
    } 
    } 
    foreach (string d in Directory.GetDirectories(sDir)) 
    { 
    DirSearch(d, files); 
    } 
    return files; 
} 

Sau đó gọi nó như thế này.

List<string> files = DirSearch("c:\foo", new List<string>()); 

Cập nhật:

Vâng unbeknownst với tôi, cho đến khi tôi đọc những câu trả lời khác dù sao, đã có một cơ chế được xây dựng trong để làm điều này. Tôi sẽ để lại câu trả lời của tôi trong trường hợp bạn quan tâm đến việc xem mã của bạn cần được sửa đổi như thế nào để làm cho nó hoạt động.

+0

Sẽ không hoạt động. 'f' không được xác định. – Bernard

+0

@Bernard: Yup, sao chép lỗi dán ... đã sửa. Cảm ơn. –

3

Bạn đang tạo ba danh sách, thay vì sử dụng một danh sách (bạn không sử dụng giá trị trả lại là DirSearch(d)).Bạn có thể sử dụng một danh sách như một tham số để tiết kiệm nhà nước:

static void Main(string[] args) 
{ 
    var list = new List<string>(); 
    DirSearch(list, "."); 

    foreach (var file in list) 
    { 
    Console.WriteLine(file); 
    } 
} 

public static void DirSearch(List<string> files, string startDirectory) 
{ 
    try 
    { 
    foreach (string file in Directory.GetFiles(startDirectory, "*.*")) 
    { 
     string extension = Path.GetExtension(file); 

     if (extension != null) 
     { 
     files.Add(file); 
     } 
    } 

    foreach (string directory in Directory.GetDirectories(startDirectory)) 
    { 
     DirSearch(files, directory); 
    } 
    } 
    catch (System.Exception e) 
    { 
    Console.WriteLine(e.Message); 
    } 
} 
2

bạn có thể làm một cái gì đó như thế này:

foreach (var file in Directory.GetFiles(MyFolder, "*.xml", SearchOption.AllDirectories)) 
     { 
      // do something with this file 
     } 
0

Sử dụng EnumerateFiles để có được các file trong thư mục lồng nhau. Sử dụng AllDirectories để recurse thư mục.

using System; 
using System.IO; 

class Program 
{ 
    static void Main() 
    { 
    // Call EnumerateFiles in a foreach-loop. 
    foreach (string file in Directory.EnumerateFiles(@"c:\files", 
     "*.xml", 
     SearchOption.AllDirectories)) 
    { 
     // Display file path. 
     Console.WriteLine(file); 
    } 
    } 
} 
Các vấn đề liên quan