সিস্টেমের জন্য একাধিক ফাইল-এক্সটেনশানগুলি অনুসন্ধানের প্যাটার্ন O


140

সেট করার জন্য সিনট্যাক্স কি একাধিক ফাইল-এক্সটেনশন হিসাবে searchPatternউপর Directory.GetFiles()? উদাহরণস্বরূপ .aspx এবং .ascx এক্সটেনশানগুলির সাহায্যে ফাইলগুলি ফিল্টার করা ।

// TODO: Set the string 'searchPattern' to only get files with
// the extension '.aspx' and '.ascx'.
var filteredFiles = Directory.GetFiles(path, searchPattern);

আপডেট : লিনকুই কোনও বিকল্প নয় , এটি প্রশ্নের মধ্যে বর্ণিত হিসাবে searchPatternপাস করতে হবে GetFiles


আমি মনে করি না এর কোনও আছে। হয় সমস্ত ফাইলের তালিকা তৈরি করুন এবং তারপরে ম্যানুয়ালি ফিল্টার করুন বা একাধিক অনুসন্ধানে একটি ইউনিয়ন সম্পাদন করুন। তবে আমি নিশ্চিত যে আমি এই ঠিক প্রশ্নটি এসও এর আগে দেখেছি।
কোডসইনচাউস


পূর্বে এখানে জিজ্ঞাসা করা হয়েছে এবং উত্তর দেওয়া হয়েছে: stackoverflow.com/questions/163162/…
ডেভিড

উত্তর:


41

আমি বিশ্বাস করি যে কোনও "বাক্সের বাইরে" সমাধান নেই, এটি ডিরেক্টরি G গেটফাইল্স পদ্ধতির একটি সীমাবদ্ধতা।

আপনার নিজস্ব পদ্ধতি লিখতে মোটামুটি সহজ যদিও এখানে একটি উদাহরণ রয়েছে

কোডটি হতে পারে:

/// <summary>
/// Returns file names from given folder that comply to given filters
/// </summary>
/// <param name="SourceFolder">Folder with files to retrieve</param>
/// <param name="Filter">Multiple file filters separated by | character</param>
/// <param name="searchOption">File.IO.SearchOption, 
/// could be AllDirectories or TopDirectoryOnly</param>
/// <returns>Array of FileInfo objects that presents collection of file names that 
/// meet given filter</returns>
public string[] getFiles(string SourceFolder, string Filter, 
 System.IO.SearchOption searchOption)
{
 // ArrayList will hold all file names
ArrayList alFiles = new ArrayList();

 // Create an array of filter string
 string[] MultipleFilters = Filter.Split('|');

 // for each filter find mathing file names
 foreach (string FileFilter in MultipleFilters)
 {
  // add found file names to array list
  alFiles.AddRange(Directory.GetFiles(SourceFolder, FileFilter, searchOption));
 }

 // returns string array of relevant file names
 return (string[])alFiles.ToArray(typeof(string));
}

7
এটি এটি করার একটি অত্যন্ত অপ্রতুল উপায়, যেহেতু আপনি প্রতিটি ফিল্টারের জন্য সম্পূর্ণ ডিরেক্টরি লুপ করবেন। পরিবর্তে আপনার প্রতিটি ফাইলের জন্য এটি পরীক্ষা করতে হবে যদি এর মধ্যে ফিল্টার থাকে তবে তালিকাটি করতে যোগ করুন। আপনি উত্তর ব্যবহার করতে পারেন এই থ্রেড ব্যাখ্যা করেছিলেন: stackoverflow.com/questions/3754118/...
ot0

190
var filteredFiles = Directory
    .GetFiles(path, "*.*")
    .Where(file => file.ToLower().EndsWith("aspx") || file.ToLower().EndsWith("ascx"))
    .ToList();

2014-07-23 সম্পাদনা করুন

দ্রুত গণনার জন্য আপনি .NET 4.5 এ এটি করতে পারেন:

var filteredFiles = Directory
    .EnumerateFiles(path) //<--- .NET 4.5
    .Where(file => file.ToLower().EndsWith("aspx") || file.ToLower().EndsWith("ascx"))
    .ToList();

ডিরেক্টরি। এমএসডিএন-এ গণিত ফাইলগুলি


5
@ মারিও ভার্নারি: GetFilesফিরে আসে string[]
jgauffin

4
আপনাকে অবশ্যই প্রান্তকালীন যুক্তি থেকে * সরিয়ে ফেলতে হবে, এটি ওয়াইল্ডকার্ডের ম্যাচ করে না।
হ্যান্স প্যাস্যান্ট

3
যদি ফাইলের এক্সটেনশনের তুলনা করা হয় তবে এটি '.Where (ফাইল => নতুন ফাইলআইফোন (ফাইল) এর মতো যথাযথ ম্যাচ ফিরে আসবে x ) '
দামিথ

3
নতুন .NET4 ভুলবেন না Directory.EnumerateFiles একটি কার্যকারিতা বুস্ট ... এর জন্য stackoverflow.com/questions/5669617/...
drzaus

6
এবং আপনি সর্বদা file.EndsWith("...", StringComparison.InvariantCultureIgnoreCase);পরিবর্তে ব্যবহার করতে পারেনToLower
ড্রাজাস

30

গেটফাইলগুলি কেবল একটি একক প্যাটার্নের সাথে মেলে তবে আপনি লিনকটি একাধিক নিদর্শন সহ গেটফিলগুলি অনুরোধ করতে ব্যবহার করতে পারেন:

FileInfo[] fi = new string[]{"*.txt","*.doc"}
    .SelectMany(i => di.GetFiles(i, SearchOption.AllDirectories))
    .ToArray();

মন্তব্য বিভাগটি এখানে দেখুন: http://www.codeproject.com/KB/aspnet/NET_DirectoryInfo.aspx


2
নিদর্শনগুলি ওভারল্যাপ হলে তারা সংঘর্ষ করবে। যেমন new string[]{"*.txt","filename.*"},। যাইহোক, কল করার জন্য Distinctপ্রকৃতপক্ষে এই সমস্যাটি সমাধান হবে না, যেহেতু ফাইলআইনফো বিষয়গুলি রেফারেন্স সমতা ব্যবহার করে তুলনা করে, অর্থগত সাম্য নয়। এটি মুছে ফেলা Distinctবা এটি পাস করে স্থির করা যেতে পারে IEqualityComparer<FileInfo>। প্রাক্তন করতে সম্পাদিত।
ব্রায়ান

আমি মনে করি যে SelectManyএটি আবার একই ফাইলের কাঠামোর (এবং আবার) পুনরাবৃত্তি করবে তাই এটি পারফরম্যান্সের ক্ষেত্রে সাব-অনুকূল হতে পারে।
দেজন

28

আমি এই পদ্ধতিটি পছন্দ করি, কারণ এটি পাঠযোগ্য এবং ডিরেক্টরিটির একাধিক পুনরাবৃত্তি এড়িয়ে চলে:

var allowedExtensions = new [] {".doc", ".docx", ".pdf", ".ppt", ".pptx", ".xls", ".xslx"}; 
var files = Directory
    .GetFiles(folder)
    .Where(file => allowedExtensions.Any(file.ToLower().EndsWith))
    .ToList();

2
আমি এটি অনেক বেশি পছন্দ করি কারণ আমাকে আমার এক্সটেনশান অ্যারে পার্স করতে হবে না এবং এটি রেজেক্স বা অন্যান্য ম্যানুয়াল কাজে যুক্ত করতে হবে না। ধন্যবাদ!
ইয়ান নিউল্যান্ড 16

@Jodrell, অথবা কেবল একটিHashSet<string>
Jodrell

এক্সটেনশনের সংখ্যা সীমিত হওয়ায় এবং এ্যান্ডস উইথ () সত্য হওয়া অবধি প্রতিটি ফাইলের জন্য অ্যারেটি পুনরাবৃত্তি হয়ে যায় বলে এক্সটেনশনের জন্য অ্যারের পরিবর্তে হ্যাশসেট <স্ট্রিং> এখানে কোনও অর্থবোধ করে না। যদি খুব বড় সংখ্যক এক্সটেনশনের জন্য পারফরম্যান্সের জন্য পদ্ধতিটি সুর করা দরকার হয়, তবে একটি হ্যাশেট ব্যবহার করা যেতে পারে। কার্যকর হওয়ার জন্য, প্রতিটি ফাইলের এক্সটেনশনের পরে ইন্ডসভিথ () - পদ্ধতির পরিবর্তে স্পষ্টভাবে মিলিত হওয়া (বিভাজন, তারপরে ম্যাচ) করা দরকার। এটি পাঠযোগ্যতার ক্ষতি করবে এবং সমস্ত বাস্তব জীবনের ব্যবহারের ক্ষেত্রে না হলে বেশিরভাগ ক্ষেত্রে তাৎপর্যপূর্ণ কাজে আসবে না। আমি এরপরে সম্প্রদায় সম্পাদনাটি ফিরিয়ে আনি।
মার্ক

15

আমি আশঙ্কা করি আপনাকে এই জাতীয় কিছু করতে হবে, আমি এখান থেকে রেজেক্সকে রূপান্তরিত করেছিলাম ।

var searchPattern = new Regex(
    @"$(?<=\.(aspx|ascx))", 
    RegexOptions.IgnoreCase);
var files = Directory.EnumerateFiles(path)
    .Where(f => searchPattern.IsMatch(f))
    .ToList();

এটি একটি দুর্দান্ত পদ্ধতির বলে মনে হচ্ছে, অনুপস্থিত অংশটি একটি নিয়মিত এক্সপ্রেশনযুক্ত (কাজ করা)
জুনিয়র মেহে

14
var filteredFiles = Directory
    .EnumerateFiles(path, "*.*") // .NET4 better than `GetFiles`
    .Where(
        // ignorecase faster than tolower...
        file => file.ToLower().EndsWith("aspx")
        || file.EndsWith("ascx", StringComparison.OrdinalIgnoreCase))
    .ToList();

অথবা, আপনার গ্লোবগুলি বিভক্ত করা এবং মার্জ করার জন্য এটি আরও দ্রুত হতে পারে (কমপক্ষে এটি পরিষ্কার দেখায়):

"*.ext1;*.ext2".Split(';')
    .SelectMany(g => Directory.EnumerateFiles(path, g))
    .ToList();

- এবং এর "মূল" আরো বিস্তারিত সঙ্গে প্রশ্ন reposting stackoverflow.com/questions/163162/...
drzaus

6

মনে রাখা সহজ, অলস এবং সম্ভবত অসম্পূর্ণ সমাধান:

Directory.GetFiles(dir, "*.dll").Union(Directory.GetFiles(dir, "*.exe"))

4

আমি নিম্নলিখিত ব্যবহার করবে:

var ext = new string[] { ".ASPX", ".ASCX" };
FileInfo[] collection = (from fi in new DirectoryInfo(path).GetFiles()
                         where ext.Contains(fi.Extension.ToUpper())
                         select fi)
                         .ToArray();

সম্পাদনা: ডিরেক্টরি এবং ডিরেক্টরিআইএনফো-র মধ্যে যথাযথ অমিল


3

".Aspx" এবং ".ascx" এক্সটেনশানগুলির সাহায্যে ফাইলগুলি পাওয়ার আরও কার্যকর উপায় যা ফাইল সিস্টেমকে বেশ কয়েকবার জিজ্ঞাসা করা থেকে বিরত থাকে এবং প্রচুর অযাচিত ফাইলগুলি ফিরিয়ে এড়িয়ে যায়, আনুমানিক অনুসন্ধানের প্যাটার্ন ব্যবহার করে ফাইলগুলি প্রাক-ফিল্টার করা এবং পরে ফলাফলটি পরিমার্জন করতে:

var filteredFiles = Directory.GetFiles(path, "*.as?x")
    .Select(f => f.ToLowerInvariant())
    .Where(f => f.EndsWith("px") || f.EndsWith("cx"))
    .ToList();

2

আমি এরকম কিছু নির্দিষ্ট করার চেষ্টা করব

var searchPattern = "as?x";

এটি কাজ করা উচিত.


Hah! আমি আশঙ্কা করছিলাম যে এসপেক্স এবং এসএসএক্স খুব একই রকম এবং এটি হ্যাক-সলিউশনটি এর মতো করে দেবে। আমি সাধারণ কিছু চাই
সেলে নীলসন

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
    public static bool CheckFiles(string pathA, string pathB)
    {
        string[] extantionFormat = new string[] { ".war", ".pkg" };
        return CheckFiles(pathA, pathB, extantionFormat);
    }
    public static bool CheckFiles(string pathA, string pathB, string[] extantionFormat)
    {
        System.IO.DirectoryInfo dir1 = new System.IO.DirectoryInfo(pathA);
        System.IO.DirectoryInfo dir2 = new System.IO.DirectoryInfo(pathB);
        // Take a snapshot of the file system. list1/2 will contain only WAR or PKG 
        // files
        // fileInfosA will contain all of files under path directories 
        FileInfo[] fileInfosA = dir1.GetFiles("*.*", 
                              System.IO.SearchOption.AllDirectories);
        // list will contain all of files that have ..extantion[]  
        // Run on all extantion in extantion array and compare them by lower case to 
        // the file item extantion ...
        List<System.IO.FileInfo> list1 = (from extItem in extantionFormat
                                          from fileItem in fileInfosA
                                          where extItem.ToLower().Equals 
                                          (fileItem.Extension.ToLower())
                                          select fileItem).ToList();
        // Take a snapshot of the file system. list1/2 will contain only WAR or  
        // PKG files
        // fileInfosA will contain all of files under path directories 
        FileInfo[] fileInfosB = dir2.GetFiles("*.*", 
                                       System.IO.SearchOption.AllDirectories);
        // list will contain all of files that have ..extantion[]  
        // Run on all extantion in extantion array and compare them by lower case to 
        // the file item extantion ...
        List<System.IO.FileInfo> list2 = (from extItem in extantionFormat
                                          from fileItem in fileInfosB
                                          where extItem.ToLower().Equals            
                                          (fileItem.Extension.ToLower())
                                          select fileItem).ToList();
        FileCompare myFileCompare = new FileCompare();
        // This query determines whether the two folders contain 
        // identical file lists, based on the custom file comparer 
        // that is defined in the FileCompare class. 
        return list1.SequenceEqual(list2, myFileCompare);
    }

2

ইন্ডস উইথ ফাংশনের পরিবর্তে আমি এর Path.GetExtension()পরিবর্তে পদ্ধতিটি বেছে নেব । এখানে সম্পূর্ণ উদাহরণ:

var filteredFiles = Directory.EnumerateFiles( path )
.Where(
    file => Path.GetExtension(file).Equals( ".aspx", StringComparison.OrdinalIgnoreCase ) ||
            Path.GetExtension(file).Equals( ".ascx", StringComparison.OrdinalIgnoreCase ) );

বা:

var filteredFiles = Directory.EnumerateFiles(path)
.Where(
    file => string.Equals( Path.GetExtension(file), ".aspx", StringComparison.OrdinalIgnoreCase ) ||
            string.Equals( Path.GetExtension(file), ".ascx", StringComparison.OrdinalIgnoreCase ) );

( StringComparison.OrdinalIgnoreCaseআপনি যদি পারফরম্যান্সের বিষয়ে যত্নশীল হন তবে ব্যবহার করুন : এমএসডিএন স্ট্রিং তুলনা )


1

এই ডেমো মত চেহারা:

void Main()
{
    foreach(var f in GetFilesToProcess("c:\\", new[] {".xml", ".txt"}))
        Debug.WriteLine(f);
}
private static IEnumerable<string> GetFilesToProcess(string path, IEnumerable<string> extensions)
{
   return Directory.GetFiles(path, "*.*")
       .Where(f => extensions.Contains(Path.GetExtension(f).ToLower()));
}

1
আপনি Path.GetExtensionব্যবহার করতে পারেন যা আছে ।
jgauffin

1

@ ড্যানিয়েল বি, এই ফাংশনের নিজস্ব সংস্করণটি লেখার পরামর্শের জন্য আপনাকে ধন্যবাদ। এটি ডিরেক্টরী.গেটফাইলেসের মতো একই আচরণ করে তবে রেজেক্স ফিল্টারিং সমর্থন করে।

string[] FindFiles(FolderBrowserDialog dialog, string pattern)
    {
        Regex regex = new Regex(pattern);

        List<string> files = new List<string>();
        var files=Directory.GetFiles(dialog.SelectedPath);
        for(int i = 0; i < files.Count(); i++)
        {
            bool found = regex.IsMatch(files[i]);
            if(found)
            {
                files.Add(files[i]);
            }
        }

        return files.ToArray();
    }

আমি এটি দরকারী খুঁজে পেয়েছি, তাই আমি ভেবেছি আমি ভাগ করে নেব।


1

@ কিউফ্যাক্টর 77 এর উত্তরের সি # সংস্করণ। এটি লিনকিউ ছাড়াই সেরা উপায়।

string[] wildcards= {"*.mp4", "*.jpg"};
ReadOnlyCollection<string> filePathCollection = FileSystem.GetFiles(dirPath, Microsoft.VisualBasic.FileIO.SearchOption.SearchAllSubDirectories, wildcards);
string[] filePath=new string[filePathCollection.Count];
filePathCollection.CopyTo(filePath,0);

এখন filePathস্ট্রিং অ্যারে রিটার্ন করুন । শুরুতে আপনার দরকার

using Microsoft.VisualBasic.FileIO;
using System.Collections.ObjectModel;

এছাড়াও আপনার রেফারেন্স যুক্ত করতে হবে Microsoft.VisualBasic


1

আপনার প্রয়োজনীয় যতগুলি এক্সটেনশান সমুদ্র সৈকতের জন্য আমি একটি সহজ উপায় করেছি এবং কোনও টোলওয়ার (), রেজিএক্স, ফোরচ না করে ...

List<String> myExtensions = new List<String>() { ".aspx", ".ascx", ".cs" }; // You can add as many extensions as you want.
DirectoryInfo myFolder = new DirectoryInfo(@"C:\FolderFoo");
SearchOption option = SearchOption.TopDirectoryOnly; // Use SearchOption.AllDirectories for seach in all subfolders.
List<FileInfo> myFiles = myFolder.EnumerateFiles("*.*", option)
    .Where(file => myExtensions
    .Any(e => String.Compare(file.Extension, e, CultureInfo.CurrentCulture, CompareOptions.IgnoreCase) == 0))
    .ToList();

নেট স্ট্যান্ডার্ড 2.0 তে কাজ করা Working


1

আপনি এটি এইভাবে করতে পারেন

new DirectoryInfo(path).GetFiles().Where(Current => Regex.IsMatch(Current.Extension, "\\.(aspx|ascx)", RegexOptions.IgnoreCase)

প্রশ্নের মধ্যে রয়েছে: লিনকুই একটি বিকল্প নয়, সুতরাং এই উত্তরটি কার্যকর নয়
আরসি

0
var filtered = Directory.GetFiles(path)
    .Where(file => file.EndsWith("aspx", StringComparison.InvariantCultureIgnoreCase) || file.EndsWith("ascx", StringComparison.InvariantCultureIgnoreCase))
    .ToList();

কোডটির জন্য অতিরিক্ত ব্যাখ্যা যুক্ত করুন। এটি আপনার উত্তরকে আরও ভালভাবে বুঝতে ওকে সহায়তা করতে পারে।
ব্যবহারকারী 2339071

-2

শুধু বলতে চাই যে আপনি যদি এর FileIO.FileSystem.GetFilesপরিবর্তে ব্যবহার করেনDirectory.GetFiles এটি ওয়াইল্ডকার্ডগুলির একটি অ্যারেটিকে অনুমতি দেবে।

উদাহরণ স্বরূপ:

Dim wildcards As String() = {"*.html", "*.zip"}
Dim ListFiles As List(Of String) = FileIO.FileSystem.GetFiles(directoryyouneed, FileIO.SearchOption.SearchTopLevelOnly, wildcards).ToList

একজন কোথায় অর্জন করবে FileIO?
জোয়েল মার্টিনেজ

1
এটি ইতিমধ্যে আপনার পরিবেশে ভিজ্যুয়াল স্টুডিওতে অন্তর্ভুক্ত করা উচিত (2015)। এটি মাইক্রোসফ্ট-ভিজুয়ালবাসিক নেমস্পেসের অংশ। আমার ক্ষেত্রে ভিজ্যুয়াল বেসিক কারণ এটি আমার পছন্দের ভাষা।
qfactor77
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.