118

Cú pháp để thiết lập nhiều phần mở rộng tập tin như searchPatterntrên Directory.GetFiles()gì? Ví dụ: lọc các tệp có phần mở rộng .aspx.ascx .

// TODO: Set the string 'searchPattern' to only get files with
// the extension '.aspx' and '.ascx'.
var filteredFiles = Directory.GetFiles(path, searchPattern);

Cập nhật : LINQ không phải là một tùy chọn , nó phải được searchPatterntruyền vào GetFiles, như được chỉ định trong câu hỏi.

|
36

Tôi tin rằng không có giải pháp "ngoài luồng", đó là một hạn chế của phương thức Directory.GetFiles.

Thật dễ dàng để viết phương pháp của riêng bạn, đây là một ví dụ .

Mã có thể là:

/// <summary>
/// Returns file names from given folder that comply to given filters
/// </summary>
/// <param name="SourceFolder">Folder with files to retrieve</param>
/// <param name="Filter">Multiple file filters separated by | character</param>
/// <param name="searchOption">File.IO.SearchOption, 
/// could be AllDirectories or TopDirectoryOnly</param>
/// <returns>Array of FileInfo objects that presents collection of file names that 
/// meet given filter</returns>
public string[] getFiles(string SourceFolder, string Filter, 
 System.IO.SearchOption searchOption)
{
 // ArrayList will hold all file names
ArrayList alFiles = new ArrayList();

 // Create an array of filter string
 string[] MultipleFilters = Filter.Split('|');

 // for each filter find mathing file names
 foreach (string FileFilter in MultipleFilters)
 {
  // add found file names to array list
  alFiles.AddRange(Directory.GetFiles(SourceFolder, FileFilter, searchOption));
 }

 // returns string array of relevant file names
 return (string[])alFiles.ToArray(typeof(string));
}
|
  • 1

    Đây là một cách rất không đủ để làm điều đó, vì bạn sẽ lặp toàn bộ thư mục cho mỗi bộ lọc. Thay vào đó, bạn nên kiểm tra từng tệp nếu nó có bộ lọc sau đó thêm vào để làm danh sách. Bạn có thể sử dụng câu trả lời được giải thích trong chuỗi này: stackoverflow.com/questions/3754118/ cấp

    – Hoàng Mỹ Tâm 11:09:11 24/12/2015
180
var filteredFiles = Directory
    .GetFiles(path, "*.*")
    .Where(file => file.ToLower().EndsWith("aspx") || file.ToLower().EndsWith("ascx"))
    .ToList();

Chỉnh sửa 2014-07-23

Bạn có thể làm điều này trong .NET 4.5 để liệt kê nhanh hơn:

var filteredFiles = Directory
    .EnumerateFiles(path) //<--- .NET 4.5
    .Where(file => file.ToLower().EndsWith("aspx") || file.ToLower().EndsWith("ascx"))
    .ToList();

Directory.Enum CảFiles trong MSDN

|
30

GetFiles chỉ có thể khớp với một mẫu duy nhất, nhưng bạn có thể sử dụng Linq để gọi GetFiles với nhiều mẫu:

FileInfo[] fi = new string[]{"*.txt","*.doc"}
    .SelectMany(i => di.GetFiles(i, SearchOption.AllDirectories))
    .ToArray();

Xem phần bình luận tại đây: http://www.codeproject.com/KB/aspnet/NET_DirectoryInfo.aspx

|
  • 1

    tại sao Distinct? Họ không nên va chạm, phải không?

    – Lý Minh Thư 20:02:58 18/09/2013
  • 1

    Chúng sẽ va chạm nếu các mẫu chồng lên nhau. Ví dụ new string[]{"*.txt","filename.*"}. Tuy nhiên, lệnh gọi Distinctkhông thực sự giải quyết vấn đề này, vì các đối tượng FileInfo so sánh bằng cách sử dụng đẳng thức tham chiếu, không phải là đẳng thức ngữ nghĩa. Nó có thể được sửa bằng cách loại bỏ Distincthoặc chuyển nó đi IEqualityComparer<FileInfo>. Chỉnh sửa để làm trước đây.

    – Ngô Tân Long 16:20:21 09/07/2015
  • 1

    Tôi nghĩ rằng điều đó SelectManysẽ lặp đi lặp lại trên cùng một cấu trúc tệp (và một lần nữa) để nó có thể không tối ưu về mặt hiệu suất.

    – Lý Thu Phong 10:20:28 19/03/2019
17

Tôi thích phương pháp này, vì nó có thể đọc được và tránh được nhiều lần lặp của thư mục:

var allowedExtensions = new [] {".doc", ".docx", ".pdf", ".ppt", ".pptx", ".xls", ".xslx"}; 
var files = Directory
    .GetFiles(folder)
    .Where(file => allowedExtensions.Any(file.ToLower().EndsWith))
    .ToList();
|
14

Tôi sợ bạn sẽ phải làm một cái gì đó như thế này, tôi đã biến đổi regex từ đây .

var searchPattern = new Regex(
    @"$(?<=\.(aspx|ascx))", 
    RegexOptions.IgnoreCase);
var files = Directory.EnumerateFiles(path)
    .Where(f => searchPattern.IsMatch(f))
    .ToList();
|
14
var filteredFiles = Directory
    .EnumerateFiles(path, "*.*") // .NET4 better than `GetFiles`
    .Where(
        // ignorecase faster than tolower...
        file => file.ToLower().EndsWith("aspx")
        || file.EndsWith("ascx", StringComparison.OrdinalIgnoreCase))
    .ToList();

Hoặc, có thể nhanh hơn để phân chia và hợp nhất các khối của bạn (ít nhất là nó trông sạch hơn):

"*.ext1;*.ext2".Split(';')
    .SelectMany(g => Directory.EnumerateFiles(path, g))
    .ToList();
|
4

Tôi sẽ sử dụng như sau:

var ext = new string[] { ".ASPX", ".ASCX" };
FileInfo[] collection = (from fi in new DirectoryInfo(path).GetFiles()
                         where ext.Contains(fi.Extension.ToUpper())
                         select fi)
                         .ToArray();

EDIT: đã sửa lỗi không khớp giữa Directory và DirectoryInfo

|
3

Giải pháp dễ nhớ, lười biếng và có lẽ không hoàn hảo:

Directory.GetFiles(dir, "*.dll").Union(Directory.GetFiles(dir, "*.exe"))
|
3

Một cách hiệu quả hơn để nhận tệp với các phần mở rộng ".aspx" và ".ascx" để tránh truy vấn hệ thống tệp nhiều lần và tránh trả lại nhiều tệp không mong muốn, là lọc trước các tệp bằng cách sử dụng mẫu tìm kiếm gần đúng và để tinh chỉnh kết quả sau đó:

var filteredFiles = Directory.GetFiles(path, "*.as?x")
    .Select(f => f.ToLowerInvariant())
    .Where(f => f.EndsWith("px") || f.EndsWith("cx"))
    .ToList();
|
2

Chỉ muốn nói rằng nếu bạn sử dụng FileIO.FileSystem.GetFilesthay vì Directory.GetFiles, nó sẽ cho phép một loạt các ký tự đại diện.

Ví dụ:

Dim wildcards As String() = {"*.html", "*.zip"}
Dim ListFiles As List(Of String) = FileIO.FileSystem.GetFiles(directoryyouneed, FileIO.SearchOption.SearchTopLevelOnly, wildcards).ToList
|
2

Thay vì hàm EndsWith, tôi sẽ chọn sử dụng Path.GetExtension()phương thức thay thế. Dưới đây là ví dụ đầy đủ:

var filteredFiles = Directory.EnumerateFiles( path )
.Where(
    file => Path.GetExtension(file).Equals( ".aspx", StringComparison.OrdinalIgnoreCase ) ||
            Path.GetExtension(file).Equals( ".ascx", StringComparison.OrdinalIgnoreCase ) );

hoặc là:

var filteredFiles = Directory.EnumerateFiles(path)
.Where(
    file => string.Equals( Path.GetExtension(file), ".aspx", StringComparison.OrdinalIgnoreCase ) ||
            string.Equals( Path.GetExtension(file), ".ascx", StringComparison.OrdinalIgnoreCase ) );

(Sử dụng StringComparison.OrdinalIgnoreCasenếu bạn quan tâm đến hiệu suất: so sánh chuỗi MSDN )

|
2
    public static bool CheckFiles(string pathA, string pathB)
    {
        string[] extantionFormat = new string[] { ".war", ".pkg" };
        return CheckFiles(pathA, pathB, extantionFormat);
    }
    public static bool CheckFiles(string pathA, string pathB, string[] extantionFormat)
    {
        System.IO.DirectoryInfo dir1 = new System.IO.DirectoryInfo(pathA);
        System.IO.DirectoryInfo dir2 = new System.IO.DirectoryInfo(pathB);
        // Take a snapshot of the file system. list1/2 will contain only WAR or PKG 
        // files
        // fileInfosA will contain all of files under path directories 
        FileInfo[] fileInfosA = dir1.GetFiles("*.*", 
                              System.IO.SearchOption.AllDirectories);
        // list will contain all of files that have ..extantion[]  
        // Run on all extantion in extantion array and compare them by lower case to 
        // the file item extantion ...
        List<System.IO.FileInfo> list1 = (from extItem in extantionFormat
                                          from fileItem in fileInfosA
                                          where extItem.ToLower().Equals 
                                          (fileItem.Extension.ToLower())
                                          select fileItem).ToList();
        // Take a snapshot of the file system. list1/2 will contain only WAR or  
        // PKG files
        // fileInfosA will contain all of files under path directories 
        FileInfo[] fileInfosB = dir2.GetFiles("*.*", 
                                       System.IO.SearchOption.AllDirectories);
        // list will contain all of files that have ..extantion[]  
        // Run on all extantion in extantion array and compare them by lower case to 
        // the file item extantion ...
        List<System.IO.FileInfo> list2 = (from extItem in extantionFormat
                                          from fileItem in fileInfosB
                                          where extItem.ToLower().Equals            
                                          (fileItem.Extension.ToLower())
                                          select fileItem).ToList();
        FileCompare myFileCompare = new FileCompare();
        // This query determines whether the two folders contain 
        // identical file lists, based on the custom file comparer 
        // that is defined in the FileCompare class. 
        return list1.SequenceEqual(list2, myFileCompare);
    }
|
2
    /// <summary>
    /// Returns the names of files in a specified directories that match the specified patterns using LINQ
    /// </summary>
    /// <param name="srcDirs">The directories to seach</param>
    /// <param name="searchPatterns">the list of search patterns</param>
    /// <param name="searchOption"></param>
    /// <returns>The list of files that match the specified pattern</returns>
    public static string[] GetFilesUsingLINQ(string[] srcDirs,
         string[] searchPatterns,
         SearchOption searchOption = SearchOption.AllDirectories)
    {
        var r = from dir in srcDirs
                from searchPattern in searchPatterns
                from f in Directory.GetFiles(dir, searchPattern, searchOption)
                select f;

        return r.ToArray();
    }
|
2

Tôi sẽ cố gắng chỉ định một cái gì đó như

var searchPattern = "as?x";

nó nên hoạt động

|
1

trông giống như bản demo này:

void Main()
{
    foreach(var f in GetFilesToProcess("c:\\", new[] {".xml", ".txt"}))
        Debug.WriteLine(f);
}
private static IEnumerable<string> GetFilesToProcess(string path, IEnumerable<string> extensions)
{
   return Directory.GetFiles(path, "*.*")
       .Where(f => extensions.Contains(Path.GetExtension(f).ToLower()));
}
|

Câu trả lời của bạn (> 20 ký tự)

Bằng cách click "Đăng trả lời", bạn đồng ý với Điều khoản dịch vụ, Chính sách bảo mật and Chính sách cookie của chúng tôi.

Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ hoặc hỏi câu hỏi của bạn.