[C#] 여러 필터를 사용하여 Directory.GetFiles ()를 호출 할 수 있습니까?

내가 사용하려고 Directory.GetFiles()같은 여러 유형의 파일 목록을 검색하는 방법을 mp3의와 jpg의를. 나는 운없이 다음 두 가지를 모두 시도했다.

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

한 번의 호출로이를 수행 할 수있는 방법이 있습니까?



답변

.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가 지적한 기억 / 성능 문제 는 매우 중요합니다.


답변

이건 어때요:

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


답변

확인할 확장명 목록이 많은 경우 다음을 사용할 수 있습니다. 나는 많은 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
}


답변

…에 대한

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)));
}

그러나 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

(그 질문에 구체적으로 어떤 LINQ를 요구하지 않기 때문에 재 게시와 ‘중복’에서 확장 : 여러 파일 확장 된 searchPattern System.IO.Directory.GetFiles에 대한 )


답변

나는 그것이 오래된 질문이지만 LINQ : (.NET40 +)

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


답변

메모리 나 성능 오버 헤드가없고 매우 우아해 보이는 하강 솔루션도 있습니다.

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


답변

Linq를 사용하는 또 다른 방법이지만 모든 것을 반환하고 메모리에서 필터링하지 않아도됩니다.

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

실제로 2 GetFiles()번의 호출 이지만 질문의 정신과 일치하고 열거 가능한 것으로 반환합니다.