क्या आप कई फिल्टर के साथ Directory.GetFiles () कॉल कर सकते हैं?


353

मैं Directory.GetFiles()कई प्रकार की फ़ाइलों की सूची को पुनः प्राप्त करने के लिए विधि का उपयोग करने की कोशिश कर रहा हूं , जैसे कि mp3's jpg' और 's'। मैंने दोनों को बिना किसी भाग्य के साथ आज़माया है:

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

क्या एक कॉल में ऐसा करने का कोई तरीका है?


3
एक साइड नोट के रूप में, एक्सटेंशन को फ़िल्टर करने के लिए GetFiles खोज पैटर्न का उपयोग करना सुरक्षित नहीं है। उदाहरण के लिए आपके पास दो फ़ाइल Test1.xls और Test2.xlsx हैं और आप खोज पैटर्न * .xls का उपयोग करके xls फ़ाइल को फ़िल्टर करना चाहते हैं, लेकिन FFiles दोनों Test1 को वापस करते हैं। .xls और Test2.xlsx अधिक जानकारी के लिए नोट खंड पढ़ें
an१

तो इसे कैसे रोका जाए?
ब्रैकेट्स

2
@ किन्नर कैसे सुरक्षित नहीं है? यह बग के बजाय एक विशेषता की तरह दिखता है।
काइल डेलाने

जवाबों:


519

.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"));

संपादित करें: कृपया टिप्पणियों को पढ़ें। पॉल फेरी ने जो सुधार का सुझाव दिया है, और जो स्मृति / प्रदर्शन को क्रिश्चियन.के बताते हैं, दोनों ही बहुत महत्वपूर्ण हैं।


10
यार, मुझे LINQ के संदर्भ में अधिक बार सोचना होगा। अच्छा समाधान!
केन प्रीस्पीसा

61
बस सुनिश्चित करें कि आप निहितार्थ को समझते हैं: यह एक स्ट्रिंग सरणी में सभी फ़ाइलों को वापस करेगा और फिर आपके द्वारा निर्दिष्ट एक्सटेंशन द्वारा फ़िल्टर करें। यह एक बड़ा मुद्दा नहीं हो सकता है अगर "C: \ Path" के पास बहुत सारी फाइलें नहीं हैं, लेकिन यह "C: \" या इस तरह की कोई मेमोरी / प्रदर्शन समस्या हो सकती है।
क्रिश्चियन.के।

24
... 2 साल बाद: अच्छा कोड, लेकिन इस के साथ बाहर देखो, अगर आपके पास एक फ़ाइल है जो .JPG के साथ समाप्त होती है तो वह इसे नहीं बनाएगी। बेहतर जोड़ेंs.ToLower().Endswith...
स्ट्रोमेनेट

107
आप बस इस्तेमाल कर सकते हैंs.EndsWith(".mp3", StringComparison.OrdinalIgnoreCase)
पॉल फेरी

119
ध्यान दें कि .NET 4.0 के साथ, आप बदल सकते हैं Directory.GetFilesके साथ Directory.EnumerateFiles, msdn.microsoft.com/en-us/library/dd383571.aspx है, जो स्मृति मुद्दों @ Christian.K कहा गया है कि नहीं आने देगा।
जिम मेंथेल डिक

60

इस बारे में कैसा है:

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/wz42302.nx


मैं अनुमान लगा रहा हूँ कि यह टॉप रेटेड उत्तर की संभावित मेमोरी कमियों से बचा जाता है? किस मामले में, इसे उच्च दर्जा दिया जाना चाहिए!
दान डब्ल्यू

11
@DanW शीर्ष रेटेड उत्तर निश्चित रूप से स्मृति पर बोझ डालता है, लेकिन मुझे लगता है कि ऐसी समस्या नहीं होनी चाहिए। मुझे यह उत्तर भी पसंद आया, लेकिन यह वास्तव में (बहुत) धीमा है तो स्वीकृत उत्तर। इस चेक SpeedTest
ओटो

धन्यवाद। खुशी है कि यह केवल दो बार धीमी गति से देखने के लिए है - मुझे लगता है कि इस बीच मैं इसके साथ रहना चाहूंगा।
दान डब्ल्यू

7
यदि केवल दो एक्सटेंशन हैं तो यह केवल दो बार धीमा है। यदि आपके पास एक्स एक्सटेंशन की सूची है, तो यह एक्स गुना अधिक धीमी होगी। क्योंकि यहां आप फंक्शन Directory.GetFiles को कई बार कॉल कर रहे हैं, जबकि दूसरे सॉल्यूशन में इसे केवल एक बार कहा जाता है।
ऑस्कर हर्मोसिला

1
@OcarHermosilla एक का उपयोग Parallel.ForEachकर उन्हें समानांतर में पा सकते हैं
FindOutIslamNow

33

यदि आपके पास जांचने के लिए एक्सटेंशन की एक बड़ी सूची है, तो आप निम्नलिखित का उपयोग कर सकते हैं। मैं बहुत सारे OR स्टेटमेंट नहीं बनाना चाहता था इसलिए मैंने जो लिखा था उसे संशोधित किया।

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
}

कृपया इसके साथ मेरी मदद करें ... जब मैं छवि को प्रिंट करता हूं तो यह इसका कुल पथ दे रहा है। मैं इसे केवल फ़ाइल के नाम पर कैसे छोटा कर सकता हूं।
नरेश

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

Path.GetExtension'.ext' लौटाता है, '* .ext' (कम से कम 3.5+) में नहीं।
nullable

2
FYI करें: आपको .lq की जरूरत है। (
jnoreiga

1
एक संभावित दोष है। हम उन दिनों से लंबे होते हैं, जहां विस्तार के लिए तीन अक्षर होना आवश्यक है। मान लें कि आप के साथ एक फ़ाइल का सामना कर सकते हैं .abc, और समर्थित एक्सटेंशन शामिल हैं .abcd। मैच होगा, हालांकि यह नहीं होना चाहिए। ठीक करने के लिए: के supportedExtensions = ".jpg|.abcd|";साथ .Contains(Path.GetExtension(s).ToLower() + "|")। यही है, परीक्षण में अपने विभाजक चरित्र को शामिल करें। महत्वपूर्ण: आपका विभाजक चरित्र भी समर्थित अपवादों में अंतिम प्रविष्टि के बाद होना चाहिए।
टूलमेकरसिटव

31

के लिये

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

यह थोड़ा तेज़ हो जाता है यदि आपको उन्हें ग्लब्स (यानी exts = new[] {"*.mp3", "*.jpg"}पहले से ही) चालू नहीं करना है ।

निम्नलिखित LinqPad परीक्षण के आधार पर प्रदर्शन मूल्यांकन (नोट: Perfसिर्फ प्रतिनिधि को 10000 बार दोहराता है) https://gist.github.com/zaus/7454021

(फिर से पोस्ट किया और 'डुप्लीकेट' से बढ़ाया के बाद से उस सवाल का विशेष रूप से कोई LINQ का अनुरोध: एकाधिक फ़ाइल एक्सटेंशन searchPattern System.IO.Directory.GetFiles के लिए )


अगर आप उन्हें ग्लब्स में बदलना नहीं चाहते हैं तो आपका क्या मतलब है "मैं थोड़ा तेज़ हो जाता हूँ"? क्या यह O (1) है या यह O (n) है (फाइलों की संख्या के संबंध में, एक्सटेंशन की संख्या नहीं)? मैंने अनुमान लगाया होगा कि यह एक्सटेंशन की संख्या के संबंध में O (1) (या O (n) है और शायद कहीं-कहीं कुछ cpu-cycles की सीमा में है ... अगर ऐसा है तो शायद यही है - प्रदर्शन वार - नगण्य
BatteryBackupnnit

@BatteryBackupUnit हाँ 2k एक्सटेंशन के खिलाफ 10k प्रतिनिधि के साथ ग्लोब बनाम str अंतर 3ms है, इसलिए हाँ तकनीकी रूप से नगण्य है (पूर्ण परिणाम लिंक देखें), लेकिन मुझे पता नहीं कितने एक्सटेंशन के लिए आपको फ़िल्टर करने की आवश्यकता है, मुझे लगता है कि यह इंगित करने लायक है अंतर; मैं यह तय करने के लिए आपको छोड़ देता हूं कि "सरलीकृत उपयोग" (यानी .FilterFiles(path, "jpg", "gif")) "स्पष्ट ग्लब्स" (यानी .FilterFiles(path, "*.jpg", "*.gif")) से बेहतर है या नहीं ।
drzaus

बहुत बहुत धन्यवाद। क्षमा करें, मैंने किसी तरह उस गिटब लिंक को छोड़ दिया। हो सकता है कि मैं अपनी स्क्रीन की रंग सेटिंग्स को अनुकूलित करूं :)
BatteryBackupUnit

क्या यह समर्थन ऐसे गधे .JPG या .MKV का विस्तार करता है?
वाहू

1
SelectMany समाधान के साथ दोष यह है कि यह एक बार फाइल एक्सटेंशन में पारित होने के बाद सभी फाइलों पर पुनरावृत्ति करेगा।
17 में से 26

16

मुझे पता है कि यह पुराना प्रश्न है लेकिन LINQ: (.NET40 +)

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

3
अच्छा विचार। file.ToLower()ऊपरी-केस एक्सटेंशन को आसानी से मिलान करने के लिए उपयोग करने पर विचार करें । और पहले एक्सटेंशन क्यों नहीं निकाला गया, इसलिए रेगेक्स को पूरे रास्ते की जांच करने की आवश्यकता नहीं है:Regex.IsMatch(Path.GetExtension(file).ToLower(), @"\.(wav|mp3|txt)");
टूलमेकरसैटव

13

वहाँ भी एक वंश समाधान है जो किसी भी स्मृति या प्रदर्शन उपरि नहीं है और काफी सुरुचिपूर्ण है लगता है:

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

1
मुझे लगता है कि मैं इसे संपादित कर सकता था ताकि यह नए स्ट्रिंग चर और एक स्प्लिट फ़ंक्शन के साथ अज्ञात असीमित संख्या में एक्सटेंशन को स्वीकार करे। लेकिन फिर भी, यह कैसे jnoreiga के समाधान से बेहतर है? क्या यह तेज है? कम मेमोरी खपत?
ब्रैकेट्स

1
एक व्यापार बंद है। यह दृष्टिकोण कई बार GetFiles को कॉल करता है, प्रति फ़िल्टर एक। उन एकाधिक कॉलों में कुछ स्थितियों में महत्वपूर्ण "प्रदर्शन ओवरहेड" हो सकता है, इसका महत्वपूर्ण लाभ यह है कि प्रत्येक GetFiles केवल मिलान फ़ाइल पथों के साथ एक सरणी देता है। मैं यह उम्मीद करूंगा कि आमतौर पर एक अच्छा प्रदर्शन परिणाम हो सकता है, शायद बेहतर प्रदर्शन भी , लेकिन इसका परीक्षण करने की आवश्यकता है। अगर GetFiles EnumerateFiles की तुलना में काफी तेज है, तो यह अभी तक का सबसे अच्छा तरीका हो सकता है। यह भी ध्यान दें कि जब IEnumerable सीधे उपयोग करने योग्य हो तो अंतिम ".ToArray ()" छोड़ा जा सकता है।
टूलमेकरसेव

11

Linq का उपयोग करने का एक और तरीका है, लेकिन सब कुछ वापस करने और स्मृति में उस पर फ़िल्टर किए बिना।

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

यह वास्तव में 2 कॉल करने के लिए है GetFiles(), लेकिन मुझे लगता है कि यह सवाल की भावना के अनुरूप है और उन्हें एक गणना में देता है।


Linq का उपयोग क्यों करें, फिर? यह एक सूची और addrange का उपयोग करने की तुलना में तेजी से होगा?
थंडरग्रो

1
मुझे नहीं पता कि क्या तेजी से होगा और नहीं लगता कि यह एक महत्वपूर्ण सवाल है। लगभग किसी भी स्थान पर आप इस समस्या के किसी भी समाधान के लिए कोड का उपयोग कर रहे हैं, प्रदर्शन में अंतर नगण्य होगा। प्रश्न यह होना चाहिए कि भविष्य में कोड की स्थिरता को कम करने के लिए क्या अधिक पठनीय है। मुझे लगता है कि यह एक उचित जवाब है क्योंकि यह एक स्रोत लाइन में डालता है, जो मुझे लगता है कि सवाल का क्या हिस्सा है, कॉल आवश्यक है और स्पष्ट रूप से उस लाइन के इरादे को व्यक्त करता है। एक ही चीज़ को पूरा करने के लिए कई चरणों के साथ सूची और जोड़ विचलित हो रहा है।
डेव राएल

7

नहीं। निम्नलिखित आज़माएँ:

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

से लिया गया: http://blogs.msdn.com/markda/archive/2006/04/20/580075.aspx


7

चलो

var set = new HashSet<string> { ".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;

getfiles में ओवरलोड यू पोस्ट नहीं किया गया है।
नवफाल

5

मैं उपयोग नहीं कर सकता .Where पद्धति का क्योंकि मैं .NET फ्रेमवर्क 2.0 में प्रोग्रामिंग कर रहा हूं (Linq केवल .NET फ्रेमवर्क 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);
    }
}

4

निम्न फ़ंक्शन कई पैटर्न पर खोज करता है, जो अल्पविराम से अलग होता है। आप एक बहिष्करण भी निर्दिष्ट कर सकते हैं, उदाहरण के लिए: "! Web.config" सभी फाइलों को खोजेगा और "web.config" को बाहर करेगा। पैटर्न मिलाया जा सकता है।

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

}

उपयोग:

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()बुरा अभ्यास है।
abatishchev

तो हमें क्या उपयोग करना चाहिए? @abatishchev
नितिन सावंत

@ नितिन:String.Equals(a, b, StringComparison.OrdinalIgnoreCase)
abatishchev

1
दरअसल, file.Extension.Equals ("। Jpg", StringComparison.OrdinalIgnoreCase) जो मुझे पसंद है। यह .ToLower या .ToUpper की तुलना में तेज़ प्रतीत होता है, या इसलिए वे कहते हैं कि मैंने हर जगह खोजा। दरअसल, .Equals == से भी तेज है, चूंकि == कॉल करता है। नल और चेक नल के लिए (क्योंकि आप null.Equals (नल) नहीं कर सकते हैं)।
थंडरगर्ल

4

.NET 2.0 में (कोई लिनक):

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

फिर इसका उपयोग करें:

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


3

बस इसे करने का एक और तरीका मिला। अभी भी एक ऑपरेशन नहीं है, लेकिन यह देखने के लिए कि अन्य लोग इसके बारे में क्या सोचते हैं, इसे फेंक देते हैं।

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

व्हाट अबाउट

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

आप जो एक्सटेंशन चाहते हैं, उसे एक स्ट्रिंग बनाएं "" .mp3.jpg.wma.wmf "और फिर जांचें कि क्या प्रत्येक फ़ाइल में वह एक्सटेंशन है जो आप चाहते हैं। यह .net 2.0 के साथ काम करता है क्योंकि यह LINQ का उपयोग नहीं करता है।

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

   }
}

इस दृष्टिकोण के साथ लाभ यह है कि आप कोड को संपादित किए बिना एक्सटेंशन जोड़ या हटा सकते हैं यानी png चित्र जोड़ने के लिए, बस myEension = "jpg.mp3.png" लिखें।


यह नहीं जानता कि क्या हैs
ब्रैकेट्स

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

नहीं ... मुझे विश्वास है कि आपको जितने फ़ाइल प्रकार चाहिए उतने कॉल करने होंगे।

मैं अपने द्वारा आवश्यक एक्सटेंशन के साथ स्ट्रिंग्स पर एक सरणी लेने के लिए एक फ़ंक्शन बनाऊंगा और फिर सभी आवश्यक कॉल करने वाले उस सरणी पर पुनरावृति करूंगा। यह फ़ंक्शन मेरे द्वारा भेजे गए एक्सटेंशन से मेल खाने वाली फ़ाइलों की एक सामान्य सूची लौटाएगा।

आशा है ये मदद करेगा।


1

मुझे एक ही समस्या थी और सही समाधान नहीं मिल रहा था इसलिए मैंने GetFiles नामक एक फ़ंक्शन लिखा:

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

यह फ़ंक्शन Directory.Getfiles()केवल एक बार कॉल करेगा ।

उदाहरण के लिए फ़ंक्शन को इस तरह से कॉल करें:

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

संपादित करें: एकाधिक एक्सटेंशन वाली एक फ़ाइल प्राप्त करने के लिए इसे उपयोग करें:

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

उदाहरण के लिए फ़ंक्शन को इस तरह से कॉल करें:

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

1

मुझे आश्चर्य है कि इतने सारे "समाधान" क्यों पोस्ट किए गए हैं?

अगर GetFiles के काम करने के तरीके के बारे में मेरी रूकी-समझ सही है, तो केवल दो विकल्प हैं और ऊपर दिए गए किसी भी समाधान को नीचे लाया जा सकता है:

  1. GetFiles, फिर फ़िल्टर करें: फास्ट, लेकिन एक मेमोरी किलर के कारण जब तक फ़िल्टर फ़िल्टर नहीं किया जाता है तब तक ओवरहेड स्टोर करने के कारण

  2. GetFiles को फ़िल्टर करें: धीमी गति से अधिक फ़िल्टर सेट किए जाते हैं, लेकिन कम मेमोरी उपयोग के रूप में कोई ओवरहेड संग्रहीत नहीं होता है।
    यह एक प्रभावशाली बेंचमार्क के साथ उपरोक्त पदों में से एक में समझाया गया है: प्रत्येक फ़िल्टर विकल्प एक अलग गेटफ़ाइल-ऑपरेशन का कारण बनता है इसलिए हार्डड्राइव का एक ही हिस्सा कई बार पढ़ा जाता है।

मेरी राय में विकल्प 1) बेहतर है, लेकिन C: \ जैसे फ़ोल्डरों पर SearchOption.AllDirectories का उपयोग करके भारी मात्रा में मेमोरी का उपयोग किया जाएगा।
इसके बाद मैं बस एक पुनरावर्ती उप-विधि बनाऊंगा जो विकल्प 1 का उपयोग करके सभी सबफ़ोल्डर्स से गुजरता है)

यह प्रत्येक फ़ोल्डर पर केवल 1 GetFiles- ऑपरेशन का कारण होना चाहिए और इसके बाद तेज़ (विकल्प 1) होना चाहिए, लेकिन केवल थोड़ी मात्रा में मेमोरी का उपयोग करें क्योंकि फ़िल्टर प्रत्येक सबफ़ोल्डर के रीडिंग को लागू करते हैं - प्रत्येक उप-फ़ोल्डर के बाद ओवरहेड हटा दिया जाता है।

अगर मैं गलत हूं कृपया मुझे सही। मैं के रूप में मैं प्रोग्रामिंग के लिए काफी नया हूँ, लेकिन अंत में इस पर अच्छा बनने के लिए चीजों की गहरी समझ हासिल करना चाहते हैं :)


1

यदि आप VB.NET (या अपने C # प्रोजेक्ट में निर्भरता का आयात कर रहे हैं) का उपयोग कर रहे हैं, तो वास्तव में एक सुविधा विधि मौजूद है जो कई एक्सटेंशनों को फ़िल्टर करने की अनुमति देती है:

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

VB.NET में इसे My-namespace के माध्यम से एक्सेस किया जा सकता है:

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

दुर्भाग्य से, ये सुविधा विधियाँ आलसी मूल्यांकन वाले संस्करण की तरह समर्थन नहीं करती हैं Directory.EnumerateFiles() करती हैं।


यह आसानी से सबसे अच्छा जवाब है और फिर भी कुछ अधिक हैकी स्वीकार किए जाते हैं। होगा प्यार तो।
रोबी कॉइन

0

मैं नहीं जानता कि क्या समाधान बेहतर है, लेकिन मैं इसका उपयोग करता हूं:

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

फ़िल्टर्ड फ़ाइलों को प्राप्त करने का एक सरल और सुरुचिपूर्ण तरीका है

var allowedFileExtensions = ".csv,.txt";


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

-1

या आप एक्सटेंशन के स्ट्रिंग को स्ट्रिंग ^ में परिवर्तित कर सकते हैं

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
यह c ++ नहीं c #
ब्रैकेट्स

-1

एक्सटेंशन को फ़िल्टर करने के लिए GetFiles खोज पैटर्न का उपयोग करना सुरक्षित नहीं है !! उदाहरण के लिए आपके पास दो फ़ाइल Test1.xls और Test2.xlsx हैं और आप खोज पैटर्न * .xls के बारे में xls फ़ाइल फ़िल्टर करना चाहते हैं, लेकिन GetFiles ने Test1.xls और Test2.xlsx दोनों को वापस किया और मुझे इसके बारे में जानकारी नहीं थी और उत्पादन में त्रुटि मिली। पर्यावरण जब कुछ अस्थायी फ़ाइलों को अचानक सही फ़ाइलों के रूप में संभाला जाता था। खोज पैटर्न था * .txt और अस्थायी फ़ाइलों का नाम था * .txt20181028_100753898 इसलिए खोज पैटर्न पर भरोसा नहीं किया जा सकता है, आपको फ़ाइल नाम पर भी अतिरिक्त जांच को जोड़ना होगा।


सवाल का जवाब नहीं देता।
रॉबी कॉइन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.