当前位置:  开发笔记 > 编程语言 > 正文

你可以使用多个过滤器调用Directory.GetFiles()吗?

如何解决《你可以使用多个过滤器调用Directory.GetFiles()吗?》经验,为你挑选了10个好方法。

我正在尝试使用该Directory.GetFiles()方法来检索多种类型的文件列表,例如mp3's和jpg's.我试过以下两个都没有运气:

Directory.GetFiles("C:\\path", "*.mp3|*.jpg", SearchOption.AllDirectories);
Directory.GetFiles("C:\\path", "*.mp3;*.jpg", SearchOption.AllDirectories);

有没有办法在一个电话中执行此操作?



1> Christoffer ..:

对于.NET 4.0及更高版本,

var files = Directory.EnumerateFiles("C:\\path", "*.*", SearchOption.AllDirectories)
            .Where(s => s.EndsWith(".mp3") || s.EndsWith(".jpg"));

对于早期版本的.NET,

var files = Directory.GetFiles("C:\\path", "*.*", SearchOption.AllDirectories)
            .Where(s => s.EndsWith(".mp3") || s.EndsWith(".jpg"));

编辑: 请阅读评论.Paul Farry建议的改进以及Christian.K指出的内存/性能问题都非常重要.


请注意,使用.NET 4.0,您可以将`Directory.GetFiles`替换为`Directory.EnumerateFiles`,http://msdn.microsoft.com/en-us/library/dd383571.aspx,这将避免@的内存问题Christian.K提到.
你可以使用`s.EndsWith(".mp3",StringComparison.OrdinalIgnoreCase)
请确保您理解其含义:这将返回字符串数组中的*all*文件,然后通过您指定的扩展名对其进行过滤.如果"C:\ Path"下面没有很多文件,那可能不是一个大问题,但可能是"C:\"之类的内存/性能问题.
... ... 2年后:好的代码,但请注意这一点,如果你有一个以.JPG结尾的文件,它将无法实现.最好添加`s.ToLower().Endswith ...`
伙计,我必须更频繁地考虑LINQ.好的解决方案
我做了一些性能改进,并在下面的答案中提供了比较代码:http://stackoverflow.com/questions/163162/can-you-call-directory-getfiles-with-multiple-filters/19961761#19961761

2> Albert..:

这个怎么样:

private static string[] GetFiles(string sourceFolder, string filters, System.IO.SearchOption searchOption)
{
   return filters.Split('|').SelectMany(filter => System.IO.Directory.GetFiles(sourceFolder, filter, searchOption)).ToArray();
}

我在这里找到了它(在评论中):http://msdn.microsoft.com/en-us/library/wz42302f.aspx


@DanW评分最高的答案肯定会给记忆带来负担,但我认为这不应该是一个问题.我也喜欢这个答案,但它实际上(比)接受的答案要慢得多.检查一下[SpeedTest](http://www.justmygame.net/wps/multiple-extensions/)
如果只有两个扩展,它只有两倍的速度.如果你有一个X扩展列表,那么它将是X倍慢.因为在这里你多次调用函数Directory.GetFiles,而在另一个解决方案中它只被调用一次.

3> jnoreiga..:

如果要检查大量扩展名,可以使用以下内容.我不想创建很多OR语句,所以我修改了lette写的内容.

string supportedExtensions = "*.jpg,*.gif,*.png,*.bmp,*.jpe,*.jpeg,*.wmf,*.emf,*.xbm,*.ico,*.eps,*.tif,*.tiff,*.g01,*.g02,*.g03,*.g04,*.g05,*.g06,*.g07,*.g08";
foreach (string imageFile in Directory.GetFiles(_tempDirectory, "*.*", SearchOption.AllDirectories).Where(s => supportedExtensions.Contains(Path.GetExtension(s).ToLower())))
{
    //do work here
}


仅供参考:您需要使用System.Linq作为.where(

4> drzaus..:

对于

var exts = new[] { "mp3", "jpg" };

你可以:

public IEnumerable FilterFiles(string path, params string[] exts) {
    return
        Directory
        .EnumerateFiles(path, "*.*")
        .Where(file => exts.Any(x => file.EndsWith(x, StringComparison.OrdinalIgnoreCase)));
}

不要忘记新的.NET4 Directory.EnumerateFiles以提高性能(Directory.EnumerateFiles与Directory.GetFiles有什么区别?)

"IgnoreCase"应该比"ToLower"更快(.EndsWith("aspx", StringComparison.OrdinalIgnoreCase)而不是.ToLower().EndsWith("aspx"))

但是,EnumerateFiles当您拆分过滤器并合并结果时,会显示真正的好处:

public IEnumerable FilterFiles(string path, params string[] exts) {
    return 
        exts.Select(x => "*." + x) // turn into globs
        .SelectMany(x => 
            Directory.EnumerateFiles(path, x)
            );
}

如果你不必将它们变成globs(即exts = new[] {"*.mp3", "*.jpg"}已经),它会变得更快.

基于以下LinqPad测试的性能评估(注意:Perf只重复代理10000次) https://gist.github.com/zaus/7454021

(转发并从'复制'扩展,因为该问题特别请求没有LINQ:System.IO.Directory.GetFiles的多个文件扩展名searchPattern)



5> 小智..:

我知道这是老问题,但LINQ :( .NET40 +)

var files = Directory.GetFiles("path_to_files").Where(file => Regex.IsMatch(file, @"^.+\.(wav|mp3|txt)$"));


好主意。考虑使用`file.ToLower()`来轻松匹配大写扩展名。而且为什么不首先提取扩展名,所以Regex不必检查整个路径:`Regex.IsMatch(Path.GetExtension(file).ToLower(),@“ \。(wav | mp3 | txt)”);`

6> Dave Rael..:

另一种使用Linq的方法,但无需返回所有内容并在内存中过滤掉.

var files = Directory.GetFiles("C:\\path", "*.mp3", SearchOption.AllDirectories).Union(Directory.GetFiles("C:\\path", "*.jpg", SearchOption.AllDirectories));

它实际上是2个调用GetFiles(),但我认为它与问题的精神一致,并将它们归还给一个可枚举的.



7> 小智..:

还有一个下降解决方案似乎没有任何内存或性能开销,并且非常优雅:

string[] filters = new[]{"*.jpg", "*.png", "*.gif"};
string[] filePaths = filters.SelectMany(f => Directory.GetFiles(basePath, f)).ToArray();



8> NotMe..:

不.请尝试以下方法:

List _searchPatternList = new List();
    ...
    List fileList = new List();
    foreach ( string ext in _searchPatternList )
    {
        foreach ( string subFile in Directory.GetFiles( folderName, ext  )
        {
            fileList.Add( subFile );
        }
    }

    // Sort alpabetically
    fileList.Sort();

    // Add files to the file browser control    
    foreach ( string fileName in fileList )
    {
        ...;
    }

摘自:http://blogs.msdn.com/markda/archive/2006/04/20/580075.aspx



9> abatishchev..:

var set = new HashSet { ".mp3", ".jpg" };

然后

Directory.GetFiles(path, "*.*", SearchOption.AllDirectories)
         .Where(f => set.Contains(
             new FileInfo(f).Extension,
             StringComparer.OrdinalIgnoreCase));

要么

from file in Directory.GetFiles(path, "*.*", SearchOption.AllDirectories)
from ext in set
where String.Equals(ext, new FileInfo(file).Extension, StringComparison.OrdinalIgnoreCase)
select file;



10> jaysponsored..:

我不能使用.Where方法,因为我在.NET Framework 2.0中编程(Linq仅在.NET Framework 3.5+中受支持).

下面的代码不区分大小写(因此.CaB.cab将被列出).

string[] ext = new string[2] { "*.CAB", "*.MSU" };

foreach (string found in ext)
{
    string[] extracted = Directory.GetFiles("C:\\test", found, System.IO.SearchOption.AllDirectories);

    foreach (string file in extracted)
    {
        Console.WriteLine(file);
    }
}

推荐阅读
虎仔球妈_459
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有