Laden...

Wie verwende ich Directory.Exists(...) mit einer Wildcard?

Erstellt von Torni vor 6 Jahren Letzter Beitrag vor 6 Jahren 2.907 Views
T
Torni Themenstarter:in
50 Beiträge seit 2014
vor 6 Jahren
Wie verwende ich Directory.Exists(...) mit einer Wildcard?

Hallo,

ich versuche es irgendwie hinzubekommen, ein Pfad mit Wildcard abzuprüfen.

Problemstellung:

Ich schaue, ob in einem bestimmten Haupt-Verzeichnis diverse Unterordner liegen (nach immer gleichen Schema) und setze einen neuen Namen zusammen:


...
                foreach (string mods in Directory.GetDirectories(sVSPfad"))
                {
                    string sCommL = Path.GetFileName(mods);
                    sK_PP = Lefts(sCommL, 2); //2 Zeichen ab Start
                    sVS_Archiv = Mid(sCommL, 4, 6); //6 Zeicehn ab 4.ter Pos
                    switch (sK_PP)
                    {
                        case "01":  // KO
                            sCommL = "A_1_" + sVS_Archiv;
                            break;
                        case "02":  // MZ
                            sCommL = "A_2_" + sVS_Archiv;
                            break;
                        case "03":  // LU
                            sCommL = "A_3_" + sVS_Archiv;
                            break;
                        case "04":  // TR
                            sCommL = "A_4_" + sVS_Archiv;
                            break;
                        case "05":  // KL
                            sCommL = "A_5_" + sVS_Archiv;
                            break;
                        default: //
                            break;
                    }

Jetzt will ich an dieser Stelle in einem anderen Laufwerk/Pfad prüfen, ob es ein Dir mit dem zusammengesetzen "sCommL"-Namen gibt.
Hierbei hängen aber immer hinter dem "sCommL"-DirNamen noch diverse Zeichen dran, die ich nicht bestimmen kann.
Mit Directory.Exists komme ich nicht weiter, da kein Wildcard möglich ist.

Man könnte per Directory.GetDirectories alle auslesen ist aber absolut ineffektiv und unschön, da in diesme Zweiten Laufwerk/Pfad bis zu 50.000 Verzeichnisse existieren.

Gibt es da eine Möglichkeit, denn ich stehe grade enorm auf dem Schlauch bzw. durchtrenne ihn ja fast.

T
2.219 Beiträge seit 2008
vor 6 Jahren

Wenn deine Dateien/Ordner nicht nach einem festen Schema angelegt werden, dann kommst du nicht drum herum alles auflisten und prüfen zu lassen.
Feste Schemen wären fixe Bezeichnungen bei Ordnern.
Wenn du diese aber nicht kennst, dann musst du alles durchprüfen.

Eine Prüfung mit Wildcard ist, wie du schon bemerkt hast, nicht möglich.
Eine Wildcard Prüfung müsste so oder so alles einladen, wie du es nun auch machen müsstest.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

T
Torni Themenstarter:in
50 Beiträge seit 2014
vor 6 Jahren

Hi T-Virus,

das einzige was noch fest im 2.LW wäre, dass hinter dem sCommL ein Unterstrich folgt ("_").
Das ist das einzige fixe folgende Zeichen..danach diverse Bezeichner.

Ich habe es fast schon befürchtet, dass dies nicht anders realisierbar ist.

16.807 Beiträge seit 2008
vor 6 Jahren

Exists funktioniert nur auf fixe Namen / Pfade.

Das liegt daran, dass Directory.Exists oder auch File.Exists nicht das Handle (WIN32_FILE_HANDLE / WIN32_FIND_DATA) abruft, mit dem zB. Dateien eines Ordners gelesen werden können, sondern es wird versucht, die Dateiattribute (WIN32_FILE_ATTRIBUTE_DATA) des Pfads zu lesen.
Gibt es Attribute zurück, dann existiert der Pfad; ansonsten eben nicht. Anhand der Attribute kann dann ermittelt werden, ob es sich um eine Datei oder ein Verzeichnis handelt.

Wie es technisch funktioniert kann man zB in meinem System.IO Ersatz anschauen: https://github.com/SchwabenCode/QuickIO oder eben im Quellcode von .NET

Win32 kann sowieso immer nur ein Element, auch bei Wildcards zurück geben.
Wildcards funktionieren in Win32 so, dass der erste Treffer mit FindFirstFile abgerufen werden muss, das dann ein Handle zurück gibt.
Alle weiteren potentiellen Treffer erfolgen mit FindNextFile, das den vorherigen Treffer (das Handle) als Eingangsparameter benötigt.
Es ist quasi nichts anderes als ein Enumerator, der Treffer für Treffer lädt.

T
Torni Themenstarter:in
50 Beiträge seit 2014
vor 6 Jahren

Danke,

auch wieder was gelernt...

C
2.121 Beiträge seit 2010
vor 6 Jahren

So viele Verzeichnisse packt Windows? Man lernt wirklich nie aus 😃
Rein aus Interesse, hast du schon ausprobiert wie lange das dauert? Vielleicht ist es ein Trost, selbst wenn der Name keine Wildcards hätte müsstest du ja für jedes Verzeichnis erneut alles durchsuchen lassen. Da wird es mit zunehmender Anzahl an Tests effektiver alles einmalig einzulesen.

T
Torni Themenstarter:in
50 Beiträge seit 2014
vor 6 Jahren

Hi Chilic,

ja ich lese jetzt alle Verzeichnisse im 2.ten LW/Pfad einmalig in ein Array und lasse dann prüfen..
Die neuen Dirs aus dem 1.ten sind auch von der Anzahl her max 3-8, so dass dies augenmerklich auch nicht feststellbar ist bzw. solch eine Prüfung nur einmal am Tag genutzt wird...

p.s. ja, der der Server packt locker diese Anzahl an Verzeichnissen 😃
Das Anzeigen in einem Explorer dauert schon etwas..aber das brauche ich ja so nicht..

T
2.219 Beiträge seit 2008
vor 6 Jahren

Windows kann auch größere Ordner und Dateimengen verarbeiten.
Der Explorer kommt hier aber nicht mehr mit und ist meisten dann auf voller CPU Last.

Ich habe hier auf einer externen eine Kopie unserer Livedaten.
Diese bestehenden aus 5-6 Hauptordnern.
Jeder davon hat dann rund 1.000+ Ordner mit bis zu 4.000 Dateien pro Ordner.
Aktuell liegen dort rund 6,5 Mio Dateien rum.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

16.807 Beiträge seit 2008
vor 6 Jahren

Der Explorer kann das problemlos, indem man den Explorer mit UNC Prefix, zB \?\C:\temp... öffnet.
Die Limits sind nicht (nur) Windows, sondern (auch) das Dateisystem.
zB sind es bei NTFS 2^32 Einträge (also irgendwas mit 4 Milliarden Elemente).

System.IO ist für solche Datenmengen einfach viel zu langsam.
Leider ist System.IO so implementiert, dass jede FileInfo/DirectoryInfo via Early Loading alle Informationen bekommen.
Das sind pro Pfad vier API Calls.

Das Handle selbst liefert (mit FindFirstFile/FindNextFile) aber mit einem Call alleine schon Dateigröße, Name und Attribute, was für 99% der Anwendungsfälle reicht und natürlich auch viel schneller ist.
Auf diesem Prinzip gibt es einige Bibliotheken, wie zB. eben mein QuickIO.
Parallelität beim Auslesen ist jedoch auf Festplatten kontraproduktiv.