myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Gemeinschaft » .NET-Komponenten und C#-Snippets » MaskMatch Klasse zum durchsuchen mehrerer Verzeichnisebenen
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

MaskMatch Klasse zum durchsuchen mehrerer Verzeichnisebenen

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
AyrA AyrA ist männlich
myCSharp.de-Mitglied

avatar-3186.png


Dabei seit: 23.09.2010
Beiträge: 60
Entwicklungsumgebung: Visual Studio 2008 Pro
Herkunft: Schweiz


AyrA ist offline

MaskMatch Klasse zum durchsuchen mehrerer Verzeichnisebenen

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Beschreibung:

Diese Klasse verarbeitet Pfadangaben, welche Platzhalter auf mehreren Ebenen enthält,
z.B: "C:\Users\*\*\*d*" oder "C:\te?t\*\q12???8*\*.xls*"

unterstützt relative Angaben, wie z.B. "..\..\*\*", welches auch relative resultate liefert

Verwendung:
Die Verwendung ist einfach:

C#-Code:
string[] Files = MaskMatch.Match(@"C:\Users\*\*\*d*", MatchType.All);

Mit dem MatchType kann angegeben werden, ob der letzte Pfadabschnitt Dateien, Verzeichnisse oder beides sucht.

Performance:
Hat mit dem Beispielaufruf oben 616 Dateien in 200 ms gefunden bei mir.

C#-Code:
using System;
using System.Collections.Generic;
using System.IO;

    [Flags]
    public enum MatchType : int
    {
        File = 1,
        Directory = 2,
        All = File | Directory
    }

    public static class MaskMatch
    {
        private static readonly char[] Masks = new char[] { '*', '?' };

        /// <summary>
        /// Durchsucht Eine Dateistruktur nach der Maske entsprechenden Dateien/Ordner
        /// </summary>
        /// <param name="Mask">Suchmaske Beispiel: C:\te?t\*\q12???8*\*.xls*</param>
        /// <param name="Condition">Suchbedingungen (Dateien, Ordner)</param>
        /// <returns>Gefundene Dateien/Ordner</returns>
        public static string[] Match(string Mask, MatchType Condition)
        {
            List<string> Matches = new List<string>();
            string[] Patterns = getPatterns(Mask);
            for (int i = 0; i < Patterns.Length; i++)
            {
                if (i == 0)
                {
                    if ((Condition & MatchType.Directory) > 0 || i < Patterns.Length - 1)
                    {
                        Matches.AddRange(getDirectories(Patterns[i]));
                    }
                    if ((Condition & MatchType.File) > 0)
                    {
                        Matches.AddRange(getFiles(Patterns[i]));
                    }
                }
                else
                {
                    string[] temp = Matches.ToArray();
                    Matches.Clear();
                    foreach (string d in temp)
                    {
                        if ((Condition & MatchType.Directory) > 0 || i < Patterns.Length - 1)
                        {
                            Matches.AddRange(getDirectories(Path.Combine(d, Patterns[i])));
                        }
                        if ((Condition & MatchType.File) > 0)
                        {
                            Matches.AddRange(getFiles(Path.Combine(d, Patterns[i])));
                        }
                    }
                }
            }

            return Matches.ToArray();
        }

        /// <summary>
        /// Durchsucht eine Dateistructur nach der Masken entsprechenden Dateien/Ordner
        /// </summary>
        /// <param name="Masks">Masken</param>
        /// <param name="Condition">Suchbedingungen (Dateien, Ordner)</param>
        /// <param name="RemoveDuplicates">Entfernen von Duplikaten</param>
        /// <returns>Gefundene Dateien/Ordner</returns>
        public static string[] Match(string[] Masks, MatchType Condition, bool RemoveDuplicates)
        {
            List<string> L = new List<string>();
            foreach (string Mask in Masks)
            {
                string[] result = Match(Mask, Condition);
                if (RemoveDuplicates)
                {
                    foreach (string entry in result)
                    {
                        if (!L.Contains(entry))
                        {
                            L.Add(entry);
                        }
                    }
                }
                else
                {
                    L.AddRange(result);
                }
            }
            return L.ToArray();
        }

        /// <summary>
        /// Teilt eine Suchmaske in Teile auf, die von System.IO Klassen verwendet werden können
        /// </summary>
        /// <param name="Mask">Komplette Suchmaske</param>
        /// <returns>Aufgeteilte Suchmaske</returns>
        private static string[] getPatterns(string Mask)
        {
            List<string> Patterns = new List<string>();
            string[] temp = Mask.Split(Path.DirectorySeparatorChar);
            string current = temp[0] + (temp[0].Contains(":") ? Path.DirectorySeparatorChar.ToString() : string.Empty);
            for (int i = 1; i < temp.Length; i++)
            {
                if (temp[i].IndexOfAny(Masks) >= 0)
                {
                    Patterns.Add(Path.Combine(current, temp[i]));
                    current = string.Empty;
                }
                else
                {
                    current = Path.Combine(current, temp[i]);
                }
            }
            return Patterns.ToArray();
        }

        /// <summary>
        /// Durchsucht Verzeichnisse nach Verzeichnissen mit der entsprechenden Maske
        /// </summary>
        /// <param name="Mask">Suchmaske (Pfad\Maske)</param>
        /// <returns>Gefundene Verzeichnisse</returns>
        private static string[] getDirectories(string Mask)
        {
            string Dir = Mask.Substring(0, Mask.LastIndexOf(Path.DirectorySeparatorChar));
            string Arg = Mask.Substring(Mask.LastIndexOf(Path.DirectorySeparatorChar) + 1);
            try
            {
                return Directory.GetDirectories(Dir, Arg);
            }
            catch
            {
            }
            return new string[0];
        }

        /// <summary>
        /// Durchsucht Verzeichnisse nach Dateien mit der entsprechenden Maske
        /// </summary>
        /// <param name="Mask">Suchmaske (Pfad\Maske)</param>
        /// <returns>Gefundene Dateien</returns>
        private static string[] getFiles(string Mask)
        {
            string Dir = Mask.Substring(0, Mask.LastIndexOf(Path.DirectorySeparatorChar));
            string Arg = Mask.Substring(Mask.LastIndexOf(Path.DirectorySeparatorChar) + 1);
            try
            {
                return Directory.GetFiles(Dir, Arg);
            }
            catch
            {
            }
            return new string[0];
        }
    }

Lizenz: WTFPL. Namensnennung (AyrA) wäre nett aber nicht erforderlich.
Ausnahmsweise mal auf Deutsch kommentiert.

Habe diese Klasse erstellt, weil ich im Internet nichts passendes gefunden habe, was nur das macht und nicht mehr.

Schlagwörter: Pfad Datei Suchpfad Dateien Mask Maske Wildcard
25.09.2014 22:03 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 14.011
Herkunft: Stuttgart/Stockholm


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Tipps:
Verzichte auf System.IO und geh direkt auf die Win32 API. Bei Netzwerkfreigaben um den Faktor 700 schneller.
Zudem unterstützt FindFirstFileEx Wildcards und schneller gehts nicht ;-)

Hab ich in QuickIO.NET auch so integriert aber noch nicht released.
25.09.2014 23:32 Beiträge des Benutzers | zu Buddylist hinzufügen
AyrA AyrA ist männlich
myCSharp.de-Mitglied

avatar-3186.png


Dabei seit: 23.09.2010
Beiträge: 60
Entwicklungsumgebung: Visual Studio 2008 Pro
Herkunft: Schweiz

Themenstarter Thema begonnen von AyrA

AyrA ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Das Problem ist dann, dass es in Mono nicht mehr kompiliert, sobald ich Windows API verwende und ich brauche dieses Script leider auch auf linux maschinen. Ansonsten wäre es überlegenswert, da je nach maske erheblich komplexere strukturen entstehen können.
26.09.2014 03:22 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 14.011
Herkunft: Stuttgart/Stockholm


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ayra, dann nimm wenigstens EnumerateFiles(); das ist auf Mono identisch implementiert aber auf Windows durch den Enumerator meist besser als GetFiles(). Komplett unterschiedliches Verhalten mit der Win32 API; nur als Tipp.
26.09.2014 17:56 Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als 5 Jahre.
Der letzte Beitrag ist älter als 5 Jahre.
Antwort erstellen


© Copyright 2003-2020 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 07.08.2020 14:35