我试图使用Directory.GetFiles()方法检索多种类型的文件列表,如mp3的和jpg的。以下两种方法我都试过了,但都没有成功:

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

有没有办法一次就能搞定?


当前回答

DirectoryInfo directory = new DirectoryInfo(Server.MapPath("~/Contents/"));

//Using Union

FileInfo[] files = directory.GetFiles("*.xlsx")
                            .Union(directory
                            .GetFiles("*.csv"))
                            .ToArray();

其他回答

Let

var set = new HashSet<string>(
    new[] { ".mp3", ".jpg" },
    StringComparer.OrdinalIgnoreCase); // ignore case
var dir = new DirectoryInfo(path);

Then

dir.EnumerateFiles("*.*", SearchOption.AllDirectories)
   .Where(f => set.Contains(f.Extension));

or

from file in dir.EnumerateFiles("*.*", SearchOption.AllDirectories)
from ext in set // makes sense only if it's just IEnumerable<string> or similar
where String.Equals(ext, file.Extension, StringComparison.OrdinalIgnoreCase)
select file;

或者你可以直接将扩展名字符串转换为string ^

vector <string>  extensions = { "*.mp4", "*.avi", "*.flv" };
for (int i = 0; i < extensions.size(); ++i)
{
     String^ ext = gcnew String(extensions[i].c_str());;
     String^ path = "C:\\Users\\Eric\\Videos";
     array<String^>^files = Directory::GetFiles(path,ext);
     Console::WriteLine(ext);
     cout << " " << (files->Length) << endl;
}

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

string[] filters = new[]{"*.jpg", "*.png", "*.gif"};
string[] filePaths = filters.SelectMany(f => Directory.GetFiles(basePath, f)).ToArray();
/// <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();
}

for

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

你可以:

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

不要忘记新的。net 4目录。EnumerateFiles用于性能提升(目录和文件的区别是什么?EnumerateFiles vs Directory.GetFiles?) “IgnoreCase”应该比“ToLower”(。EndsWith("aspx", stringcompare . ordinalignorecase)而不是。tolower ().EndsWith("aspx"))

但EnumerateFiles的真正好处体现在你拆分过滤器并合并结果时:

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

如果你不需要将它们转换为glob(即exts = new[] {"*.mp3", "*.jpg"}),它会变得更快一些。

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

(从'duplicate'重新发布和扩展,因为这个问题特别要求没有LINQ:多个文件扩展searchPattern for System.IO.Directory.GetFiles)