2010-09-22 42 views
5

Cách đọc tên tệp với phần mở rộng dll từ thư mục và từ thư mục con của nó đệ quy bằng cách sử dụng biểu thức LINQ hoặc LAMBDA.Cách đọc tên tệp đệ quy từ thư mục con bằng cách sử dụng LINQ

Bây giờ tôi đang sử dụng vòng lặp Nested for-each để thực hiện việc này. Có cách nào để thực hiện điều này bằng cách sử dụng biểu thức LINQ hoặc LAMBDA không?

Trả lời

17

Bạn không cần phải sử dụng LINQ để làm điều này - đó là built into the framework:

string[] files = Directory.GetFiles(directory, "*.dll", 
            SearchOption.AllDirectories); 

hoặc if you're using .NET 4:

IEnumerable<string> files = Directory.EnumerateFiles(directory, "*.dll", 
                SearchOption.AllDirectories); 

Thành thật mà nói, LINQ là không lớn về đệ quy. Bạn có thể muốn viết phương pháp mở rộng đệ quy đa năng của riêng bạn. Với mức độ thường xuyên loại này của câu hỏi được hỏi, tôi nên thực sự làm điều đó bản thân mình một chút thời gian ...

+0

cảm ơn bạn ... nó bao gồm các tổng con đường. Tôi chỉ cần tên của tập tin như 'foo.dll ' –

+4

@Pramodh: Vì vậy, hãy sử dụng' Path.GetFileName'. –

+1

Cần lưu ý rằng những phương pháp này có những sai sót nghiêm trọng, tuy nhiên: nếu bất kỳ ngoại lệ I/O nào xảy ra, toàn bộ kết quả sẽ bị hủy bỏ. Trong biến thể GetFiles, điều này có nghĩa là nó thường trả về không có kết quả nào, và trong biến thể EnumerateFiles, liệt kê sẽ bị tạm dừng bất cứ khi nào xuất hiện lỗi I/O đầu tiên (chẳng hạn như quyền bị từ chối). –

2
IEnumerable<string> filenames = Directory.GetFiles(searchDirectory, "*.dll", 
                SearchOption.AllDirectories) 
             .Select(s => Path.GetFileName(s)); 

Directory.GetFiles() trả về đường dẫn đầy đủ của file phù hợp với mô hình tìm kiếm được xác định trong thư mục chỉ định. Select chiếu từng phần tử của trình tự fullpath vào một biểu mẫu mới, chỉ có tên tệp.

0

Đọc tệp và thư mục thường được thực hiện với các lớp nằm trong không gian tên System.IO. Vì vậy, bước đầu tiên sẽ bao gồm việc nhận tất cả các tệp mà bạn cần đọc bằng phương thức Directory.EnumerateFiles và sau đó cho từng tệp tương ứng với tiêu chí tìm kiếm của bạn, hãy đọc nội dung bằng cách sử dụng phương thức File.ReadAllBytes.

3

Nếu bạn thực sự muốn làm điều đó với một biểu thức lambda đệ quy ở đây bạn đi:

Action<string, List<string>> discoverFiles = null; 

discoverFiles = new Action<string, List<string>>((dir, list) => 
    { 
     try 
     { 
      foreach (var subDir in Directory.GetDirectories(dir)) 
       discoverFiles(string.Concat(subDir), list); 

      foreach (var dllFile in Directory.GetFiles(dir, "*.dll")) 
      { 
       var fileNameOnly = Path.GetFileName(dllFile); 
       if (!list.Contains(fileNameOnly)) 
        list.Add(fileNameOnly); 
      } 
     } 
     catch (IOException) 
     { 
      // decide what to do here 
     } 
    }); 

// usage: 
var targetList = new List<string>(); 
discoverFiles("c:\\MyDirectory", targetList); 

foreach (var item in targetList) 
    Debug.WriteLine(item); 

Lưu ý: điều này có lẽ chậm hơn (và cách khó khăn hơn để đọc/debug/duy trì) nhiều lần so với câu trả lời trước đó, nhưng nó không dừng lại nếu có một ngoại lệ I/O ở đâu đó.

+0

Nó có thể làm với một số tái cấu trúc để phân tách mối quan tâm (chủ yếu là đệ quy lặp lại từ việc lọc và thêm vào danh sách), nhưng tôi đã sử dụng và điểm chuẩn một cái gì đó tương tự cho một tìm kiếm tập tin nhà phát triển; nó hoạt động gần như tốt như hàm dựng sẵn (và đó là khi đọc từ bộ nhớ cache - nếu I/O được tách ra, không có sự khác biệt) - và nó có lợi thế là làm việc ngay cả khi một số đường dẫn quá dài hoặc bất cứ thứ gì. –

4

này trả chỉ tập tin tên + phần mở rộng:

DirectoryInfo di = new DirectoryInfo(@"d:\somewhere\"); 
var q = from i in di.GetFiles("*.dll", SearchOption.AllDirectories) 
     select i.Name; 

này trả chỉ tên tập tin mà không cần phần mở rộng:

DirectoryInfo di = new DirectoryInfo(@"d:\somewhere\"); 
var q = from i in di.GetFiles("*.dll", SearchOption.AllDirectories) 
     select System.IO.Path.GetFileNameWithoutExtension(i.Name); 
Các vấn đề liên quan