Traversieren in allen Unterordnern, aber auch Dateien im Hauptordner



  • Guten Tag,

    ich möchte eine Funktion nutzen, die nicht nur alle Sub-Ordner durchsucht, sondern auch die Dateien in dem Zielordner mitsucht, die nicht in einem Sub-Ordnern sind, sondern die lose in dem Ordner drin liegen.

    Ich habe etwas gebaut, das zwar funktioniert, mir aber irgendwie nicht sehr schick - oder sogar fehleranfällig - erscheint.

    Da ich die Funktion für ziemlich viele Programm brauchen werde, würde ich mich hier über Feedback freuen.

    Viele Grüße, Yvonne

    /*Diese Funktion traversiert durch die Ordner und Unterordner*/
            public static void WriteAllFiles(string ordner)
            {
                try
                {
                    foreach (string d in Directory.GetDirectories(ordner))
                    {
                        foreach (string f in Directory.GetFiles(d)) //alle Unterordner
                        {
                            tw.WriteLine("Datei: " + f);
                        }
                        WriteAllFiles(d);
                    }
    
                    foreach (string f in Directory.GetFiles(ordner)) //der übergeordnete Ordner
                    {
                        tw.WriteLine("Datei: " + f);
                    }
                }
                catch (System.Exception excpt)
                {
                    tw.WriteLine(excpt.Message);
                }
            }
    

  • Administrator

    Directory.GetFiles(rootDir, "*", SearchOption.AllDirectories);
    

    http://msdn.microsoft.com/en-us/library/ms143316.aspx
    http://msdn.microsoft.com/en-us/library/ms143448.aspx

    Oder alternativ über EnumerateFiles :
    http://msdn.microsoft.com/en-us/library/dd383571.aspx

    Grüssli



  • Hi,

    in der Form ist die Methode noch falsch, du gibst Dateien doppelt aus. Du gibst die Files aller Unterordner aus und machst dann einen rekursiven Aufruf für jeden Unterorder. Das führt dazu, dass in der unteren Schleife abermals die gleichen Pfade ausgegeben werden. Der Sonderfall ist nur das oberste Verzeichnis, das der Benutzer beim Aufruf übergibt.

    Eine Exception in einer Utility-Methode direkt zu fangen und irgendwo auszugeben ist wenig hilfreich für den Aufrufer. Lass eine potentielle Exception doch einfach rausfliegen statt sie zu verschleiern.



  • Vielen Dank euch beiden.

    Er gibt die Dateien jetzt nicht mehr doppelt aus und guckt auch in alle Unterordner, aber nach wie vor habe ich eine eher unschöne Krücke für die Dateien im Hauptordner.
    Ich meine, wenn es funktioniert, bin ich zufrieden, ich wundere mich nur, weil all die Code-Beispiele, die ich gefunden habe mit weniger Zeilen ausgekommen sind und nicht den Ober-Ordner nochmal extra abfrühstücken mussten.

    /*Diese Funktion traversiert durch die Ordner und Unterordner*/
            public static void WriteAllFiles(string ordner)
            {
                try
                {
                    foreach (string d in Directory.GetDirectories(ordner))
                    {
                        WriteAllFiles(d);
                    }
    
                    foreach (string f in Directory.GetFiles(ordner)) //der übergeordnete Ordner
                    {
                        tw.WriteLine("Datei: " + f);
                    }
                }
                catch (System.Exception)
                {
    
                }
            }
    


  • so ist es ja auch Unsinn, ich möchte ja in der Main mit den Dateien weiterarbeiten und nicht alles innerhalb der Funktion erledigen.



  • Wieso bist du dann nicht bei einem der Beispiele geblieben?



  • Guten Tag,

    die von mir gefunden Beispiele haben nicht so funktioniert wie ich mir das vorgestellt hatte.

    Z. B. dieses hier:

    public static void WriteAllFiles(DirectoryInfo Directory)
    {
     foreach (System.IO.DirectoryInfo d in Directory.GetDirectories())
                    {
                        WriteAllFiles(d);
                    }
                    foreach (System.IO.FileInfo f in Directory.GetFiles())
                    {
                        tw.WriteLine("Datei: " + f.FullName);
                        tw.WriteLine("Datei: " + f.Extension);
                    }
    }
    

    Es macht exakt das was ich möchte und auch korrekt, aber ich möchte mit den Ergebnissen in der Main weiterarbeiten und nicht in der Funktion, da normalerweise ja mehr kommt als nur die Dateien auszugeben.

    Ich möchte also die gefundenen Dateien wieder an die Main übergeben.

    Viele Grüße



  • Und wo ist das Problem ? 😕
    Nimm diesen Code, viel einfacher gehts nicht:

    public static void WriteAllFiles(string path) 
    { 
        IEnumerable<string> files = Directory.EnumerateFiles("path");
        foreach(string file in files)
        {
            //Variante 1
            FileInfo info = new FileInfo(file);
            tw.WriteLine("Datei: " + info.FullName);
            tw.WriteLine("Datei: " + info.Extension); 
    
            //Variante 2
            tw.WriteLine("Datei: " + file);
            tw.WriteLine("Datei: " + Path.GetExtension(file));
        }
    }
    

    Wenn du die Dateien noch irgendwo brauchst machst du halt erneut "Directory.EnumerateFiles("path");".



  • Hallo Yvonne1978,

    dann gib die Ergebnismenge von der Methode zurück, dann kannst du damit auch in der Main arbeiten.



  • Moin,

    entschuldige, die Enumerable-Sache hat bei mir nicht funktioniert, da müsste ich mich wohl erst einlesen.

    @inflames: Ja, genau, das habe ich versucht, aber es gelang mir nicht den gesamten array zurückzugeben, es kam immer nur der letzte Wert zurück.
    Andere Funktionen mit Rückgabewerten (bool usw.) waren kein Problem, aber beim string [] array muss ich wohl noch etwas tiefer graben.

    Vermutlich merkt man, dass ich in C# noch sehr neu bin...

    Vielen Dank erstmal für euren Input.



  • Erstelle eine List<String> und gib diese zurück.

    public static List<string> WriteAllFiles(DirectoryInfo Directory)
    {
        List<string> files = new List<string>();
    
        foreach (System.IO.DirectoryInfo d in Directory.GetDirectories())
        {
            WriteAllFiles(d);
        }
    
        foreach (System.IO.FileInfo f in Directory.GetFiles())
        {
            tw.WriteLine("Datei: " + f.FullName);
            tw.WriteLine("Datei: " + f.Extension);
            files.Add(f.FullName);
        }
    
        return files;
    }
    

    Anschließend hast du in der aufrufenden Methode die Liste der Dateien und kannst über diese iterieren um deine zusätzlichen Aktionen auszuführen.



  • Hallo zusammen und vielen Dank für eure Tipps und Hilfe, mittlerweile habe ich es geschafft und kann die Dateien auch in einem String Array zurückgeben (über den Umweg ArrayList, da ich zunächst ja die Länge des Array nicht kenne).

    class DirSearchRekursiv
        {
            public static string directorypath;
            public static string[] Files;
            public static ArrayList rueckgabe = new ArrayList();
            public static int len;
    
            /*Methode Ordner inkl. Unterordner durchsuchen + Dateien in ArrayList ausgeben*/
            public static string[] SearchAllFiles(string path)
            {
                foreach (string d in Directory.GetDirectories(path))
                {
                    SearchAllFiles(d);
                }
                foreach (string f in Directory.GetFiles(path))
                {
                    rueckgabe.Add(f);
                }
    
                len = DirSearchRekursiv.rueckgabe.Count; //Länge der ArrayList
    
                /*Umwandlung der ArrayList in ein string Array*/
                string[] arrfiles = (string[])DirSearchRekursiv.rueckgabe.ToArray(typeof(string));
    
                return arrfiles;
            }
        }
    


  • public static IEnumerable<string> SearchAllFiles(string path)
    {
        if (string.IsNullOrEmpty(path) || !Directory.Exists(path))
            return null;
    
        return Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories);
    }
    

    Was spricht gegen diese Variante?



  • Yvonne1978 schrieb:

    ArrayList

    ArrayList gehört in die Restmülltonne. Dort soll sie auch bleiben und wir reden nie wieder darüber.

    Ernsthaft: Wie alt ist Dein Buch? Seit bald 10 Jahren gibt es Generics in C# und damit auch die List<>-Klasse, mit der Du typsicher und ohne gecaste dynamisch wachsende Arrays zur Verfügung hast. Ich frage nur, weil immer und immer wieder Leute mit ArrayList antanzen und ich nicht verstehe wo man sowas heute noch lernt.



  • Hallo freaky,

    generell würde ich deine Variante auch empfehlen, jedoch kann es Probleme bei geschützten Unterordnern (z.B. Systemordnern) geben, da dann einfach eine Exception fliegt und die Rekursion wird abgebrochen.

    Daher besser [Snippet] Verzeichnisse und Dateien rekursiv durchlaufen



  • Achso und Yvonne1978, schau mal was passiert wenn Du Deine Methode zweimal aufrufst. Dadurch, dass alles static ist und die List nicht reinitialisiert wird, kriegst Du falsche Werte.



  • Hallo zusammen,

    vielen Dank.

    Es ist richtig, ich hatte gestern oder so das Problem, dass static ints nicht reinitialisiert wurden (wenn auch in einem anderen Zusammenhang) und daher musste ich eines meiner Programme umbauen.

    Und es ist mir mit meiner Methoden ebenfalls passiert, dass sie beim Systemordner C:\ eine Exception geworfen hat.

    Ich schaue mir also sehr gern die Beiträge in dem Link an und peppe meine Methode dementsprechend auf. Schließlich benutze ich sie ja so ungefähr bei fast jedem Programm...

    Ich habe mittlerweile so viel gelesen (einiges ist tatsächlich älter und noch vom Stand 4.0) und nachgeschlagen, dass ich mich gar nicht mehr entsinnen kann, woher ich das mit der ArrayList habe.

    Ich gräme mich jetzt aber nicht sehr, immerhin hat die Methode bisher funktioniert und ich habe ja alle Fäden in der Hand, diese jetzt mit moderneren Datentypen zu verbessern.

    Da ich noch nicht sehr lange programmiere, versuche ich, die Probleme mit dem zu lösen was ich kenne, "IEnumerable<string>" sieht erstmal fremd aus und muss nachgeschlagen werden. Es sieht für meine Anfängeraugen viel wilder aus als
    eine ArrayList.

    Womöglich graben wir Anfänger daher immer wieder die ArrayList aus und man kriegt sie einfach nicht totgetreten. 😉

    Viele Grüße, Yvonne


Anmelden zum Antworten