Directory.GetFiles () öğesini birden çok filtreyle çağırabilir misiniz?


354

'S ' ve 's Directory.GetFiles()gibi birden çok türde dosyaların bir listesini almak için yöntemi kullanmaya çalışıyorum . Şanssız her ikisini de denedim:mp3jpg

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

Bunu tek bir çağrıda yapmanın bir yolu var mı?


3
Yan not olarak, uzantıyı filtrelemek için GetFiles arama kalıbını kullanmak güvenli değildir. Örneğin iki Test1.xls ve Test2.xlsx dosyanız var ve xls dosyasını arama kalıbı * .xls kullanarak filtrelemek istiyorsunuz, ancak GetFiles her iki Test1'i döndürüyor .xls ve Test2.xlsx. Daha fazla bilgi için Not Bölümü'nü okuyun
kiran

Peki bunu nasıl önleyebilirim?
Parantez

2
@kiran Bu nasıl güvenli değil? Bu bir hata yerine bir özellik gibi görünüyor.
Kyle Delaney

Yanıtlar:


521

.NET 4.0 ve sonraki sürümleri için,

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

.NET'in önceki sürümleri için,

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

edit: Lütfen yorumları okuyun. Paul Farry'nin önerdiği gelişme ve Christian.K'nın belirttiği bellek / performans sorunu çok önemlidir.


10
Dostum, LINQ açısından daha sık düşünmeliyim. Güzel çözüm!
Ken Pespisa

61
Ancak etkileri anladığınızdan emin olun: bu, bir dize dizisindeki tüm dosyaları döndürür ve ardından belirttiğiniz uzantılara göre filtreler. "C: \ Path" altında çok fazla dosya yoksa bu büyük bir sorun olmayabilir, ancak "C: \" ile ilgili bir bellek / performans sorunu veya bunun gibi bir şey olabilir.
Christian.K

24
... 2 yıl sonra: Güzel bir kod, ama buna dikkat edin, eğer .JPG ile biten bir dosyanız varsa bunu yapmaz. Daha iyi ekleyins.ToLower().Endswith...
Stormenet

107
sadece kullanabilirsinizs.EndsWith(".mp3", StringComparison.OrdinalIgnoreCase)
Paul Farry

119
.NET 4.0 Directory.GetFilesile Directory.EnumerateFiles, @ Christian.K'nın bahsettiği bellek sorunlarını önleyecek msdn.microsoft.com/en-us/library/dd383571.aspx ile değiştirebileceğinizi unutmayın .
Jim Mischel

60

Buna ne dersin:

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

Burada buldum (yorumlarda): http://msdn.microsoft.com/en-us/library/wz42302f.aspx


Sanırım bu en çok puan alan cevabın potansiyel hafıza tuzaklarını önler? Bu durumda, daha yüksek olarak derecelendirilmelidir!
Dan W

11
@DanW En yüksek oy alan cevap kesinlikle hafızaya yük bindirir ama bence böyle bir sorun olmamalı. Ben de bu cevabı beğendim, ama aslında kabul edilen cevaptan çok daha yavaş. Bu SpeedTest'i
OttO

Teşekkürler. Sadece iki kat daha yavaş olduğunu görmekten memnunum - bu arada düşünüyorum.
Dan W

7
Sadece iki uzantı varsa sadece iki kat daha yavaştır. X uzantıları listeniz varsa, X kat daha yavaş olacaktır. Çünkü burada Directory.GetFiles işlevini birkaç kez çağırırken, diğer çözümde sadece bir kez çağrılır.
Oscar Hermosilla

1
@OscarHermosilla Parallel.ForEachBunları paralel olarak almak için kullanabilirsiniz
FindOutIslamNow

33

Kontrol etmek için geniş bir uzantı listeniz varsa aşağıdakileri kullanabilirsiniz. Ben lette ne yazdım değiştirilmiş yani OR ifadeler çok oluşturmak istemiyordu.

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
}

Bu konuda bana yardım edin lütfen ... imageFile yazdırdığımda toplam yolunu veriyor. Sadece dosyanın ismine nasıl küçültebilirim.
Naresh

1
System.IO.Path.GetFileName (imageFile)
jnoreiga

Path.GetExtension'.ext' değil, '.ext' döndürür (en azından 3.5+).
null

2
FYI: .where için System.Linq'e ihtiyacınız var (
jnoreiga

1
Potansiyel bir kusur var. Uzantıların tam olarak üç karakter olması gereken günleri geride bıraktık. Diyelim ki bir dosyayla karşılaşabilirsiniz .abcve supportExtensions içerir .abcd. Eşleşecek, ancak olmamalı. Düzeltmek için: supportedExtensions = ".jpg|.abcd|";ile .Contains(Path.GetExtension(s).ToLower() + "|"). Yani, ayırıcı karakterinizi teste dahil edin. ÖNEMLİ: ayırıcı karakterinizin supportExceptions içindeki LAST girdisinden sonra olması gerekir.
ToolmakerSteve

31

için

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

Yapabilirdiniz:

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

Ancak EnumerateFilesfiltreleri böldüğünüzde ve sonuçları birleştirdiğinizde gerçek faydası ortaya çıkar:

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

Bunları globlara dönüştürmek zorunda kalmazsanız (yani exts = new[] {"*.mp3", "*.jpg"}zaten) biraz daha hızlı olur .

Aşağıdaki LinqPad testine dayanan performans değerlendirmesi (not: Perftemsilci 10000 kez tekrarlanır) https://gist.github.com/zaus/7454021

(bu soru özellikle LINQ istemediğinden 'yinelenen' için çoğaltıldı ve genişletildi: System.IO.Directory.GetFiles için birden fazla dosya uzantısı searchPattern )


"Onları küreye dönüştürmek zorunda değilsen biraz daha hızlı olur" derken ne demek istiyorsun? O (1) mi yoksa O (n) mi (dosya sayısı ile ilgili olarak, uzantı sayısı ile değil)? O (1) (veya uzantı sayısı açısından O (n)) ve muhtemelen birkaç cpu döngüsü aralığında bir yerde olduğunu tahmin ederdim ... Bu durumda, muhtemelen - performans akıllıca - ihmal edilebilir
BatteryBackupUnit

@BatteryBackupUnit evet 2 uzantılara karşı 10k tekrar ile glob vs str farkı 3ms'dir, bu yüzden evet teknik olarak ihmal edilebilir (mükemmel sonuçlar bağlantısına bakın), ancak kaç tane uzantı için filtrelemeniz gerektiğini bilmiyorum. farktır; Ben "basitleştirilmiş kullanım" (yani .FilterFiles(path, "jpg", "gif")) "açık glob" (yani .FilterFiles(path, "*.jpg", "*.gif")) daha iyi olup olmadığına karar vermek size kalmış .
drzaus

mükemmel teşekkürler. Üzgünüm bir şekilde o github bağlantısı üzerinden atladım. Belki de ekran renk ayarlarımı uyarlamalıyım :)
BatteryBackupUnit

Bu, ass .JPG veya .MKV gibi büyük harf uzantısını destekliyor mu?
Wahyu

1
SelectMany çözeltisiyle kusur dosyası başına uzatma geçirilen bir kez tüm dosyaları üzerinde yineleme olacaktır.
26 17

16

Eski bir soru olduğunu biliyorum ama LINQ: (.NET40 +)

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

3
İyi bir fikir. Büyük file.ToLower()harf uzantılarını kolayca eşleştirmek için kullanmayı düşünün . Ve neden ilk önce uzantıyı çıkarmıyorsunuz, bu yüzden Regex'in tüm yolu incelemesi gerekmiyor: Regex.IsMatch(Path.GetExtension(file).ToLower(), @"\.(wav|mp3|txt)");
ToolmakerSteve

13

Herhangi bir bellek veya performans yükü olmayan ve oldukça zarif görünen bir iniş çözümü de var:

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

1
Yeni dize değişkeni ve bir Split işlevi ile bilinmeyen sınırsız sayıda uzantıyı kabul edecek şekilde düzenleyebilirim. Ama o zaman bile, bu jnoreiga'nın çözümünden nasıl daha iyi? Daha hızlı mı? Daha az bellek tüketiyor musunuz?
Parantez

1
Bir değiş tokuş var. Bu yaklaşım GetFiles'i filtre başına bir defa olmak üzere birçok kez çağırır. Bu birden fazla çağrı bazı durumlarda önemli "performans yükü" olabilir , Her GetFiles sadece eşleşen dosya yolları ile bir dizi döndürmek önemli avantajı vardır . Bunun genellikle iyi bir performans sonucu, hatta daha üstün bir performans olmasını beklerdim , ancak bunun test edilmesi gerekiyor. GetFiles, EnumerateFiles'dan önemli ölçüde daha hızlıysa, bu en iyi yaklaşım olabilir. Ayrıca, IEnumerable doğrudan kullanılabilir olduğunda son ".ToArray ()" öğesinin atlanabileceğini unutmayın.
ToolmakerSteve

11

Linq'i kullanmanın başka bir yolu, ancak her şeyi geri döndürmek ve bellekte filtrelemek zorunda kalmadan.

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

Aslında 2 çağrı GetFiles(), ama bence sorunun ruhu ile tutarlı ve onları bir numaralandırılabilir döndürür.


Neden Linq kullanıyorsunuz? Liste ve addrange kullanmaktan daha hızlı olur mu?
ThunderGr

1
neyin daha hızlı olacağını bilmiyorum ve bunun önemli bir soru olduğunu düşünmüyorum. bu soruna herhangi bir çözüm için kodu kullanmak istediğiniz hemen hemen her yerde, performans farkı göz ardı edilebilir. soru, kodun gelecekte korunmasını kolaylaştırmak için neyin daha okunabilir olduğu konusunda olmalıdır. Ben bu makul bir cevap olduğunu düşünüyorum çünkü bu bir kaynak hattı içine koyar, ki bu soru ne arzu bir parçası olduğunu düşünüyorum, gerekli aramalar ve açıkça bu satırın niyetini ifade eder. liste ve addrange aynı şeyi başarmak için birden fazla adımla dikkat dağıtıyor.
Dave Rael

7

Hayır! Takip etmeyi dene:

List<string> _searchPatternList = new List<string>();
    ...
    List<string> fileList = new List<string>();
    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 )
    {
        ...;
    }

Alındığı yer: http://blogs.msdn.com/markda/archive/2006/04/20/580075.aspx


7

İzin Vermek

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

Sonra

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

veya

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

getfiles yüklenen u aşırı yük yok.
nawfal

5

.WhereYöntem kullanamıyorum çünkü .NET Framework 2.0'da programlama yapıyorum (Linq yalnızca .NET Framework 3.5 ve sonraki sürümlerinde desteklenmektedir).

Kod aşağıda harf duyarlı (öyle değil .CaBya .cabda listelenir).

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

4

Aşağıdaki işlev virgülle ayrılmış birden çok desende arama yapar. Bir hariç tutma da belirtebilirsiniz, örneğin: "! Web.config" tüm dosyaları arayacak ve "web.config" dosyasını hariç tutacaktır. Desenler karıştırılabilir.

private string[] FindFiles(string directory, string filters, SearchOption searchOption)
{
    if (!Directory.Exists(directory)) return new string[] { };

    var include = (from filter in filters.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries) where !string.IsNullOrEmpty(filter.Trim()) select filter.Trim());
    var exclude = (from filter in include where filter.Contains(@"!") select filter);

    include = include.Except(exclude);

    if (include.Count() == 0) include = new string[] { "*" };

    var rxfilters = from filter in exclude select string.Format("^{0}$", filter.Replace("!", "").Replace(".", @"\.").Replace("*", ".*").Replace("?", "."));
    Regex regex = new Regex(string.Join("|", rxfilters.ToArray()));

    List<Thread> workers = new List<Thread>();
    List<string> files = new List<string>();

    foreach (string filter in include)
    {
        Thread worker = new Thread(
            new ThreadStart(
                delegate
                {
                    string[] allfiles = Directory.GetFiles(directory, filter, searchOption);
                    if (exclude.Count() > 0)
                    {
                        lock (files)
                            files.AddRange(allfiles.Where(p => !regex.Match(p).Success));
                    }
                    else
                    {
                        lock (files)
                            files.AddRange(allfiles);
                    }
                }
            ));

        workers.Add(worker);

        worker.Start();
    }

    foreach (Thread worker in workers)
    {
        worker.Join();
    }

    return files.ToArray();

}

Kullanımı:

foreach (string file in FindFiles(@"D:\628.2.11", @"!*.config, !*.js", SearchOption.AllDirectories))
            {
                Console.WriteLine(file);
            }

4
List<string> FileList = new List<string>();
DirectoryInfo di = new DirectoryInfo("C:\\DirName");

IEnumerable<FileInfo> fileList = di.GetFiles("*.*");

//Create the query
IEnumerable<FileInfo> fileQuery = from file in fileList
                                  where (file.Extension.ToLower() == ".jpg" || file.Extension.ToLower() == ".png")
                                  orderby file.LastWriteTime
                                  select file;

foreach (System.IO.FileInfo fi in fileQuery)
{
    fi.Attributes = FileAttributes.Normal;
    FileList.Add(fi.FullName);
}

file.Extension.ToLower()kötü bir uygulamadır.
abatishchev

o zaman ne kullanmalıyız? @abatishchev
Nitin

@Nitin:String.Equals(a, b, StringComparison.OrdinalIgnoreCase)
abatishchev

1
Aslında file.Extension.Equals (". Jpg", StringComparison.OrdinalIgnoreCase) tercih ettiğim şey bu. .ToLower veya .ToUpper'dan daha hızlı gibi görünüyor, ya da aradığım her yerde diyorlar. Aslında .Equals == değerinden daha hızlıdır, çünkü == çağırır .Equals ve null olup olmadığını denetler (Çünkü null.Equals (null) yapamazsınız)
ThunderGr

4

.NET 2.0'da (Linq yok):

public static List<string> GetFilez(string path, System.IO.SearchOption opt,  params string[] patterns)
{
    List<string> filez = new List<string>();
    foreach (string pattern in patterns)
    {
        filez.AddRange(
            System.IO.Directory.GetFiles(path, pattern, opt)
        );
    }


    // filez.Sort(); // Optional
    return filez; // Optional: .ToArray()
}

Sonra kullanın:

foreach (string fn in GetFilez(path
                             , System.IO.SearchOption.AllDirectories
                             , "*.xml", "*.xml.rels", "*.rels"))
{}

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

//Using Union

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

3

Sadece başka bir yol buldum. Hala bir operasyon değil, diğer insanların bu konuda ne düşündüğünü görmek için dışarı atıyor.

private void getFiles(string path)
{
    foreach (string s in Array.FindAll(Directory.GetFiles(path, "*", SearchOption.AllDirectories), predicate_FileMatch))
    {
        Debug.Print(s);
    }
}

private bool predicate_FileMatch(string fileName)
{
    if (fileName.EndsWith(".mp3"))
        return true;
    if (fileName.EndsWith(".jpg"))
        return true;
    return false;
}

3

Ne dersin

string[] filesPNG = Directory.GetFiles(path, "*.png");
string[] filesJPG = Directory.GetFiles(path, "*.jpg");
string[] filesJPEG = Directory.GetFiles(path, "*.jpeg");

int totalArraySizeAll = filesPNG.Length + filesJPG.Length + filesJPEG.Length;
List<string> filesAll = new List<string>(totalArraySizeAll);
filesAll.AddRange(filesPNG);
filesAll.AddRange(filesJPG);
filesAll.AddRange(filesJPEG);

2

İstediğiniz uzantıları tek bir dize yapın (ör. ".Mp3.jpg.wma.wmf") ve ardından her dosyanın istediğiniz uzantıyı içerip içermediğini kontrol edin. Bu, LINQ kullanmadığı için .net 2.0 ile çalışır.

string myExtensions=".jpg.mp3";

string[] files=System.IO.Directory.GetFiles("C:\myfolder");

foreach(string file in files)
{
   if(myExtensions.ToLower().contains(System.IO.Path.GetExtension(s).ToLower()))
   {
      //this file has passed, do something with this file

   }
}

Bu yaklaşımın avantajı, kodu düzenlemeden uzantıları ekleyebilmeniz veya kaldırabilmenizdir, yani png resimleri eklemek için sadece myExtensions = ". Jpg.mp3.png" yazın.


ne olduğunu bilmiyors
Parantez

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

Hayır ... İstediğiniz dosya türleri kadar arama yapmanız gerektiğine inanıyorum.

Kendimi ihtiyacım uzantıları ile dizeleri bir dizi alarak bir işlev oluşturmak ve daha sonra gerekli tüm çağrıları yaparak bu dizi yineleme. Bu işlev, gönderdiğim uzantılarla eşleşen dosyaların genel bir listesini döndürür.

Umarım yardımcı olur.


1

Aynı sorunu yaşadım ve doğru çözümü bulamadım, bu yüzden GetFiles adlı bir işlev yazdım:

/// <summary>
/// Get all files with a specific extension
/// </summary>
/// <param name="extensionsToCompare">string list of all the extensions</param>
/// <param name="Location">string of the location</param>
/// <returns>array of all the files with the specific extensions</returns>
public string[] GetFiles(List<string> extensionsToCompare, string Location)
{
    List<string> files = new List<string>();
    foreach (string file in Directory.GetFiles(Location))
    {
        if (extensionsToCompare.Contains(file.Substring(file.IndexOf('.')+1).ToLower())) files.Add(file);
    }
    files.Sort();
    return files.ToArray();
}

Bu işlev Directory.Getfiles()yalnızca bir kez çağıracaktır .

Örneğin, işlevi şu şekilde çağırın:

string[] images = GetFiles(new List<string>{"jpg", "png", "gif"}, "imageFolder");

DÜZENLEME: Birden çok uzantıya sahip bir dosya almak için şu dosyayı kullanın:

/// <summary>
    /// Get the file with a specific name and extension
    /// </summary>
    /// <param name="filename">the name of the file to find</param>
    /// <param name="extensionsToCompare">string list of all the extensions</param>
    /// <param name="Location">string of the location</param>
    /// <returns>file with the requested filename</returns>
    public string GetFile( string filename, List<string> extensionsToCompare, string Location)
    {
        foreach (string file in Directory.GetFiles(Location))
        {
            if (extensionsToCompare.Contains(file.Substring(file.IndexOf('.') + 1).ToLower()) &&& file.Substring(Location.Length + 1, (file.IndexOf('.') - (Location.Length + 1))).ToLower() == filename) 
                return file;
        }
        return "";
    }

Örneğin, işlevi şu şekilde çağırın:

string image = GetFile("imagename", new List<string>{"jpg", "png", "gif"}, "imageFolder");

1

Acaba neden bu kadar çok "çözüm" var?

GetFiles'in nasıl çalıştığına dair çaylak anlayışım doğru ise, sadece iki seçenek vardır ve yukarıdaki çözümlerden herhangi biri bunlara getirilebilir:

  1. GetFiles, sonra filtre: Hızlı, ancak filtreler uygulanana kadar ek yükün depolanması nedeniyle bir bellek katili

  2. GetFiles iken Filtrele: Daha fazla filtre ayarlanır, ancak ek bellek depolanmadığı için düşük bellek kullanımı olur.
    Bu, etkileyici bir kıyaslama ile yukarıdaki yazılardan birinde açıklanmaktadır: Her filtre seçeneği ayrı bir GetFile işlemine neden olur, böylece sabit sürücünün aynı kısmı birkaç kez okunur.

Bence Seçenek 1) daha iyidir, ancak C: \ gibi klasörlerde SearchOption.AllDirectories kullanmak büyük miktarda bellek kullanır.
Bu nedenle, sadece seçenek 1'i kullanarak tüm alt klasörlerden geçen özyinelemeli bir alt yöntem yaparım)

Bu, her klasörde yalnızca 1 GetFiles işlemine neden olur ve bu nedenle hızlı olur (Seçenek 1), ancak filtreler her alt klasörün okuduğu -> ek yükü her alt klasörden sonra silindikten sonra yalnızca küçük bir bellek kullanın.

Yanlışım varsa lütfen düzelt. Programlamaya oldukça yeni dediğim gibi ama sonunda bu konuda iyi olmak için daha derin bir anlayış kazanmak istiyorum :)


1

VB.NET kullanıyorsanız (veya bağımlılığı C # projenize aktardıysanız), aslında birden çok uzantı için filtrelemeye izin veren bir kolaylık yöntemi vardır:

Microsoft.VisualBasic.FileIO.FileSystem.GetFiles("C:\\path", Microsoft.VisualBasic.FileIO.SearchOption.SearchAllSubDirectories, new string[] {"*.mp3", "*.jpg"});

VB.NET'te buna My-namespace üzerinden erişilebilir:

My.Computer.FileSystem.GetFiles("C:\path", FileIO.SearchOption.SearchAllSubDirectories, {"*.mp3", "*.jpg"})

Ne yazık ki, bu kolaylık yöntemleri, tembel olarak değerlendirilen bir varyantı desteklemiyor Directory.EnumerateFiles().


Bu kolayca en iyi cevaptır ve yine de çok daha hacky bir şey kabul edilir. Çok sevmeliyim.
Robbie Coyne

0

hangi çözüm daha iyi olduğunu bilmiyorum, ama bunu kullanın:

String[] ext = "*.ext1|*.ext2".Split('|');

            List<String> files = new List<String>();
            foreach (String tmp in ext)
            {
                files.AddRange(Directory.GetFiles(dir, tmp, SearchOption.AllDirectories));
            }

0

Filtrelenmiş dosyaları almanın basit ve zarif bir yolu

var allowedFileExtensions = ".csv,.txt";


var files = Directory.EnumerateFiles(@"C:\MyFolder", "*.*", SearchOption.TopDirectoryOnly)
                .Where(s => allowedFileExtensions.IndexOf(Path.GetExtension(s)) > -1).ToArray(); 

-1

Veya uzantı dizesini String ^ biçimine dönüştürebilirsiniz

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

2
Bu c ++ değil c #
Parantez

-1

Uzantıyı filtrelemek için GetFiles arama modelini kullanmak güvenli değildir !! Örneğin iki Test1.xls ve Test2.xlsx dosyanız var ve xls dosyasını arama kalıbı * .xls kullanarak filtrelemek istiyorsunuz, ancak GetFiles Test1.xls ve Test2.xlsx dosyalarını geri döndürüyor Bunun farkında değildim ve üretimde hata aldım bazı geçici dosyaların aniden doğru dosyalar olarak işlendiği ortam. Arama kalıbı * .txt ve geçici dosyalar * .txt20181028_100753898 olarak adlandırıldı. Bu nedenle arama kalıbına güvenilemiyor, dosya adlarına da ek kontrol eklemeniz gerekiyor.


Soruya cevap vermiyor.
Robbie Coyne
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.