2013-11-27 36 views
10

Tôi đang sử dụng các dòng sau vào trả hồ sơ cụ thể ...GetFiles() - Tìm kiếm mô hình

FileInfo file in nodeDirInfo.GetFiles("*.sbs", option) 

Nhưng có những file khác trong thư mục với phần mở rộng ".sbsar", và nó là nhận họ quá. Làm thế nào tôi có thể phân biệt giữa ".sbs" và ".sbsar" trong mẫu tìm kiếm?

+1

Bạn không thể (ít nhất là với GetFiles/GetDirectories). Đây là "giới hạn" của mẫu tìm kiếm. Bạn nên lặp qua các kết quả và lọc thủ công các kết quả bạn muốn. – varocarbas

+0

cũng xem xét điều này: http://msdn.microsoft.com/en-us/library/wz42302f(v=vs.110).aspx –

+0

có thể trùng lặp của [đối sánh tệp mở rộng chính xác với GetFiles()?] (http://stackoverflow.com/questions/5573063/exact-file-extension-match-with-getfiles) – Borja

Trả lời

4

Thử tính năng này, được lọc bằng tiện ích mở rộng tệp.

FileInfo[] files = nodeDirInfo.GetFiles("*", SearchOption.TopDirectoryOnly). 
      Where(f=>f.Extension==".sbs").ToArray<FileInfo>(); 
3

Đó là hành vi của API Win32 (FindFirstFile) nằm bên dưới GetFiles() được phản ánh cho bạn.

Bạn sẽ cần phải tự lọc nếu bạn phải sử dụng GetFiles(). Ví dụ:

GetFiles("*", searchOption).Where(s => s.EndsWith(".sbs", 
    StringComparison.InvariantCultureIgnoreCase)); 

Hoặc hiệu quả hơn:

EnumerateFiles("*", searchOption).Where(s => s.EndsWith(".sbs", 
    StringComparison.InvariantCultureIgnoreCase)); 

Lưu ý rằng tôi sử dụng StringComparison.InvariantCultureIgnoreCase để đối phó với thực tế là tên tập tin Windows là case-insensitive.

Nếu hiệu suất là một vấn đề, đó là nếu tìm kiếm phải xử lý các thư mục với số lượng tệp lớn thì sẽ hiệu quả hơn để thực hiện lọc hai lần: một lần trong cuộc gọi tới GetFiles hoặc EnumerateFiles và một lần để xóa tên tệp không mong muốn. Ví dụ:

GetFiles("*.sbs", searchOption).Where(s => s.EndsWith(".sbs", 
    StringComparison.InvariantCultureIgnoreCase)); 
EnumerateFiles("*.sbs", searchOption).Where(s => s.EndsWith(".sbs", 
    StringComparison.InvariantCultureIgnoreCase)); 
+0

@Joey Điều đó chỉ cảm thấy một chút bẩn đối với tôi, nhân đôi bộ lọc. Nhưng có lẽ nó sẽ có một ý nghĩa hoàn hảo.Nếu không thì tôi chỉ muốn có một bộ lọc. –

+0

Đó là nhanh hơn, mặc dù ;-) Trong thử nghiệm nhỏ của tôi ở đây (chạy trên thư mục nguồn hoàn chỉnh của chúng tôi, tìm kiếm '* .cpp') nó nhanh hơn khoảng 10-25% để xác định bộ lọc trong' GetFiles'. 'EnumerateFiles' hơi chậm hơn, nhưng có thể sử dụng ít bộ nhớ hơn, đặc biệt là cho các tập kết quả lớn. – Joey

+0

@Joey Vâng, tôi nghĩ điều đó là hợp lý. Tôi đoán nó đi xuống đến một sự cân bằng giữa perf và độ tinh khiết! Tôi đã trình bày điều này trong câu trả lời ngay bây giờ. –

9

Vấn đề bạn gặp phải là limitation của mẫu tìm kiếm, trong API Win32.

Một searchPattern có phần mở rộng tập tin (ví dụ * .txt) chính xác ba nhân vật trả về file có một phần mở rộng của ba hoặc nhiều ký tự, nơi ba nhân vật đầu tiên khớp với đuôi tệp quy định tại các searchPattern .

Giải pháp của tôi là để tự lọc các kết quả, sử dụng LINQ:

nodeDirInfo.GetFiles("*.sbs", option).Where(s => s.EndsWith(".sbs"), 
    StringComparison.InvariantCultureIgnoreCase)); 
+2

Bạn không tính đến trường hợp thư ở đây. –

+0

Đó là sự thật, cố định. –

0

của nó đề cập trong docs

Khi sử dụng các nhân vật dấu ký tự đại diện trong một searchPattern, một searchPattern với một tập tin mở rộng của chính xác ba ký tự trả về các tệp có phần mở rộng gồm ba ký tự trở lên.Khi sử dụng dấu hỏi hoang dã ký tự thẻ, phương thức này chỉ trả lại các tệp khớp với đuôi tệp được chỉ định.

+0

Thật tuyệt vời nếu điều này đúng. Thật không may, nó không phải là và và ở đây có một tập mới của các mô tả nghèo của searchPattern trong MSDN :) Tôi cảm thấy tò mò và đã làm một số xét nghiệm và ở đây đi đến kết luận của tôi ... – varocarbas

+0

@varocarbas thực sự..wonder nơi để sử dụng '? .OP có thể sử dụng '* a? .sbs'..Đó sẽ yêu cầu' a' ở đâu đó trong tên tệp – Anirudha

+2

'nodeDirInfo.GetFiles (" 5? .txt ");' trả về bất kỳ tệp nào chỉ bằng .txt (không .txtwhatever) có chứa hai ký tự trong tên, một trong số chúng là một 5. 'nodeDirInfo.GetFiles (".. txt ");' Trả về bất kỳ tệp .txt nào chỉ với một ký tự trong tên của nó (không bao gồm .txtwhatever). Bạn chỉ có thể nhận được * .txt bằng cách sử dụng phương thức '????. Txt' nếu bạn biết độ dài tối đa của tên tệp mà bạn đang tìm kiếm (??. Txt retuns tất cả các tệp có 1 hoặc 2 ký tự trong tên của nó ; ??? .txt tất cả những cái có 1,2 và 3, v.v ...). – varocarbas

Các vấn đề liên quan