Listen Sie alle Dateien und Verzeichnisse in einem Verzeichnis + Unterverzeichnissen auf


109

Ich möchte alle Dateien und Verzeichnisse auflisten, die in einem Verzeichnis und in Unterverzeichnissen dieses Verzeichnisses enthalten sind. Wenn ich C: \ als Verzeichnis wählen würde, würde das Programm jeden Namen jeder Datei und jedes Ordners auf der Festplatte erhalten, auf die es Zugriff hatte.

Eine Liste könnte so aussehen

fd \ 1.txt
fd \ 2.txt
fd \ a \
fd \ b \
fd \ a \ 1.txt
fd \ a \ 2.txt
fd \ a \ a \
fd \ a \ b \
fd \ b \ 1.txt
fd \ b \ 2.txt
fd \ b \ a
fd \ b \ b
fd \ a \ a \ 1.txt
fd \ a \ a \ a \
fd \ a \ b \ 1.txt
fd \ a \ b \ a
fd \ b \ a \ 1.txt
fd \ b \ a \ a \
fd \ b \ b \ 1.txt
fd \ b \ b \ a

Durchsuchen Sie den System.IO-Namespace nach Klassen und Methoden , die Ihnen möglicherweise helfen.
Lucero

Schauen Sie sich diese Frage an und lassen Sie den Teil fallen, in dem er einem Muster entspricht.
Dasblinkenlight

Antworten:


192
string[] allfiles = Directory.GetFiles("path/to/dir", "*.*", SearchOption.AllDirectories);

Wo *.*ist das Muster, um Dateien abzugleichen?

Wenn das Verzeichnis auch benötigt wird, können Sie folgendermaßen vorgehen:

 foreach (var file in allfiles){
     FileInfo info = new FileInfo(file);
 // Do something with the Folder or just add them to a list via nameoflist.add();
 }

1
Wird nicht wirklich funktionieren ... Lsit<>Klasse? Was gibt GetFiles zurück? Und was ist mit den Verzeichnisnamen, die ebenfalls angefordert wurden?
Lucero

1
Die GetFilesMethode gibt ein String-Array zurück.
Guffa

Tatsächlich ... Sie haben Recht ... Ich lerne Qt vor ungefähr 2 Tagen und habe mich ein wenig geirrt
Ruslan F.

Dies funktioniert möglicherweise, schlägt jedoch häufig mit einer UnauthorizedAccessException fehl. Wie würden nur Verzeichnisse durchsucht, auf die zugegriffen werden kann?
derp_in_mouth

es bedeutet, dass in Ihrem System diese App nicht genügend Berechtigungen hat
Ruslan F.

50

Directory.GetFileSystemEntriesexistiert in .NET 4.0+ und gibt sowohl Dateien als auch Verzeichnisse zurück. Nennen Sie es so:

string[] entries = Directory.GetFileSystemEntries(path, "*", SearchOption.AllDirectories);

Beachten Sie, dass es nicht mit Versuchen fertig wird, den Inhalt von Unterverzeichnissen aufzulisten, auf die Sie keinen Zugriff haben (UnauthorizedAccessException), aber möglicherweise für Ihre Anforderungen ausreichend ist.


3
Dies ist bei weitem die beste Antwort hier. Es werden alle Dateien und Ordner in einer Codezeile abgerufen, was keiner der anderen tut.
Steve Smith

15

Verwenden Sie die Methoden GetDirectoriesund GetFiles, um die Ordner und Dateien abzurufen.

Verwenden Sie die , um die Ordner und Dateien auch in den Unterordnern abzurufen.SearchOption AllDirectories


Verwenden Sie Teilzeichenfolge , um den linken Teil des Namens abzuschneiden. :)
Lucero

@Lucero Wie und warum würdest du das machen? Pathbietet zuverlässigere Methoden.
Gusdor

@Gusdor Sie können gerne einen geeigneteren Weg vorschlagen Path, um einen festen linken Teil des Pfades zu entfernen, z. B. "C:" im angegebenen Beispiel.
Lucero

@Lucero mein Kommentar war schlecht formuliert. 'Use substring ' sagt mir nicht viel und ich musste in linqpad stecken bleiben, um eine schöne Lösung abzuleiten. Was wäre zum Beispiel der Parameter? Wirst du tun path.SubString(2), um Laufwerksbuchstaben und Doppelpunkt naiv zu entfernen? Was ist, wenn das Verzeichnis eine Netzwerkfreigabe ist? Ich schlage Pathals zuverlässige Methode vor, weil sie in diesem Bereich viele Extras liefern kann. In diesem Fall können Sie schreiben filePath.Substring(Path.GetPathRoot(filePath).Length). Ja, hier wird Teilzeichenfolge verwendet, da dies am präzisesten ist.
Gusdor

10
public static void DirectorySearch(string dir)
{
    try
    {
        foreach (string f in Directory.GetFiles(dir))
        {
            Console.WriteLine(Path.GetFileName(f));
        }
        foreach (string d in Directory.GetDirectories(dir))
        {
            Console.WriteLine(Path.GetFileName(d));
            DirectorySearch(d);
        }
    }
    catch (System.Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

3
Es würde Ihre Antwort verbessern, wenn Sie eine kleine Erklärung hinzufügen könnten, was der Code tut.
Alex

Es geht rekursiv durch das Verzeichnis und druckt Dateinamen oder Verzeichnisnamen. Für jedes innere Verzeichnis wird dieselbe Funktion aufgerufen. Für weitere Informationen: stackoverflow.com/questions/929276/…
I.Schritt

3

Ich fürchte, die GetFilesMethode gibt eine Liste der Dateien zurück, aber nicht die Verzeichnisse. Die Liste in der Frage fordert mich auf, dass das Ergebnis auch die Ordner enthalten sollte. Wenn Sie mehr benutzerdefinierte Liste möchten, können Sie versuchen, rufen GetFilesund GetDirectoriesrekursiv. Versuche dies:

List<string> AllFiles = new List<string>();
void ParsePath(string path)
{
    string[] SubDirs = Directory.GetDirectories(path);
    AllFiles.AddRange(SubDirs);
    AllFiles.AddRange(Directory.GetFiles(path));
    foreach (string subdir in SubDirs)
        ParsePath(subdir);
}

Tipp: Sie können FileInfound DirectoryInfoKlassen verwenden, wenn Sie ein bestimmtes Attribut überprüfen müssen.


1

Sie können FindFirstFile verwenden, das ein Handle zurückgibt und dann rekursiv eine Funktion aufruft, die FindNextFile aufruft. Dies ist ein guter Ansatz, da die referenzierte Struktur mit verschiedenen Daten wie alternativeName, lastTmeCreated, modifiziert, Attributen usw. Gefüllt wird

Wenn Sie jedoch das .net-Framework verwenden, müssen Sie den nicht verwalteten Bereich betreten.


1

Einige verbesserte Versionen mit maximaler Stufe, um in das Verzeichnis zu gelangen, und Option zum Ausschließen von Ordnern:

using System;
using System.IO;

class MainClass {
  public static void Main (string[] args) {

    var dir = @"C:\directory\to\print";
    PrintDirectoryTree(dir, 2, new string[] {"folder3"});
  }


  public static void PrintDirectoryTree(string directory, int lvl, string[] excludedFolders = null, string lvlSeperator = "")
  {
    excludedFolders = excludedFolders ?? new string[0];

    foreach (string f in Directory.GetFiles(directory))
    {
        Console.WriteLine(lvlSeperator+Path.GetFileName(f));
    } 

    foreach (string d in Directory.GetDirectories(directory))
    {
        Console.WriteLine(lvlSeperator + "-" + Path.GetFileName(d));

        if(lvl > 0 && Array.IndexOf(excludedFolders, Path.GetFileName(d)) < 0)
        {
          PrintDirectoryTree(d, lvl-1, excludedFolders, lvlSeperator+"  ");
        }
    }
  }
}

Eingabeverzeichnis:

-folder1
  file1.txt
  -folder2
    file2.txt
    -folder5
      file6.txt
  -folder3
    file3.txt
  -folder4
    file4.txt
    file5.txt

Ausgabe der Funktion (Inhalt von Ordner5 ist aufgrund des Level-Limits ausgeschlossen und Inhalt von Ordner3 ist ausgeschlossen, da er sich im Array "Ausgeschlossene Ordner" befindet):

-folder1
  file1.txt
  -folder2
    file2.txt
    -folder5
  -folder3
  -folder4
    file4.txt
    file5.txt

0

Wenn Sie keinen Zugriff auf einen Unterordner in der Verzeichnisstruktur haben, stoppt Directory.GetFiles und löst die Ausnahme aus, die zu einem Nullwert in der empfangenden Zeichenfolge [] führt.

Hier finden Sie diese Antwort unter https://stackoverflow.com/a/38959208/6310707

Es verwaltet die Ausnahme innerhalb der Schleife und arbeitet weiter, bis der gesamte Ordner durchlaufen wird.


0

der logische und geordnete Weg:

using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;

namespace DirLister
{
class Program
{
    public static void Main(string[] args)
    {
        //with reflection I get the directory from where this program is running, thus listing all files from there and all subdirectories
        string[] st = FindFileDir(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location));
        using ( StreamWriter sw = new StreamWriter("listing.txt", false ) )
        {
            foreach(string s in st)
            {
                //I write what I found in a text file
                sw.WriteLine(s);
            }
        }
    }

    private static string[] FindFileDir(string beginpath)
    {
        List<string> findlist = new List<string>();

        /* I begin a recursion, following the order:
         * - Insert all the files in the current directory with the recursion
         * - Insert all subdirectories in the list and rebegin the recursion from there until the end
         */
        RecurseFind( beginpath, findlist );

        return findlist.ToArray();
    }

    private static void RecurseFind( string path, List<string> list )
    {
        string[] fl = Directory.GetFiles(path);
        string[] dl = Directory.GetDirectories(path);
        if ( fl.Length>0 || dl.Length>0 )
        {
            //I begin with the files, and store all of them in the list
            foreach(string s in fl)
                list.Add(s);
            //I then add the directory and recurse that directory, the process will repeat until there are no more files and directories to recurse
            foreach(string s in dl)
            {
                list.Add(s);
                RecurseFind(s, list);
            }
        }
    }
}
}

Könnten Sie bitte eine Erklärung oder Inline-Kommentare abgeben, was Ihr Code bewirkt?
MarthyM

Natürlich, getan, aber es sollte selbsterklärend sein, es ist eine einfache Schleifenrekursion durch alle Verzeichnisse und Dateien
Sascha

0

Im folgenden Beispiel werden Dateien und Unterordner in einem Verzeichnisbaum, der Ausnahmen behandelt, am schnellsten (nicht parallelisiert) aufgelistet. Es wäre schneller, Directory.EnumerateDirectories mit SearchOption.AllDirectories zu verwenden, um alle Verzeichnisse aufzulisten. Diese Methode schlägt jedoch fehl, wenn eine UnauthorizedAccessException oder PathTooLongException auftritt.

Verwendet den generischen Stack-Auflistungstyp, bei dem es sich um einen LIFO-Stapel (Last In First Out) handelt und der keine Rekursion verwendet. Unter https://msdn.microsoft.com/en-us/library/bb513869.aspx können Sie alle Unterverzeichnisse und Dateien auflisten und diese Ausnahmen effektiv behandeln.

    public class StackBasedIteration
{
    static void Main(string[] args)
    {
        // Specify the starting folder on the command line, or in 
        // Visual Studio in the Project > Properties > Debug pane.
        TraverseTree(args[0]);

        Console.WriteLine("Press any key");
        Console.ReadKey();
    }

    public static void TraverseTree(string root)
    {
        // Data structure to hold names of subfolders to be
        // examined for files.
        Stack<string> dirs = new Stack<string>(20);

        if (!System.IO.Directory.Exists(root))
        {
            throw new ArgumentException();
        }
        dirs.Push(root);

        while (dirs.Count > 0)
        {
            string currentDir = dirs.Pop();
            string[] subDirs;
            try
            {
                subDirs = System.IO.Directory.EnumerateDirectories(currentDir); //TopDirectoryOnly
            }
            // An UnauthorizedAccessException exception will be thrown if we do not have
            // discovery permission on a folder or file. It may or may not be acceptable 
            // to ignore the exception and continue enumerating the remaining files and 
            // folders. It is also possible (but unlikely) that a DirectoryNotFound exception 
            // will be raised. This will happen if currentDir has been deleted by
            // another application or thread after our call to Directory.Exists. The 
            // choice of which exceptions to catch depends entirely on the specific task 
            // you are intending to perform and also on how much you know with certainty 
            // about the systems on which this code will run.
            catch (UnauthorizedAccessException e)
            {                    
                Console.WriteLine(e.Message);
                continue;
            }
            catch (System.IO.DirectoryNotFoundException e)
            {
                Console.WriteLine(e.Message);
                continue;
            }

            string[] files = null;
            try
            {
                files = System.IO.Directory.EnumerateFiles(currentDir);
            }

            catch (UnauthorizedAccessException e)
            {

                Console.WriteLine(e.Message);
                continue;
            }

            catch (System.IO.DirectoryNotFoundException e)
            {
                Console.WriteLine(e.Message);
                continue;
            }
            // Perform the required action on each file here.
            // Modify this block to perform your required task.
            foreach (string file in files)
            {
                try
                {
                    // Perform whatever action is required in your scenario.
                    System.IO.FileInfo fi = new System.IO.FileInfo(file);
                    Console.WriteLine("{0}: {1}, {2}", fi.Name, fi.Length, fi.CreationTime);
                }
                catch (System.IO.FileNotFoundException e)
                {
                    // If file was deleted by a separate application
                    //  or thread since the call to TraverseTree()
                    // then just continue.
                    Console.WriteLine(e.Message);
                    continue;
                }
                catch (UnauthorizedAccessException e)
                {                    
                    Console.WriteLine(e.Message);
                    continue;
                }
            }

            // Push the subdirectories onto the stack for traversal.
            // This could also be done before handing the files.
            foreach (string str in subDirs)
                dirs.Push(str);
        }
    }
}

Verwenden von Aufgaben für eine große Anzahl von Dateien und Verzeichnissen?
PreguntonCojoneroCabrón

msdn.microsoft.com/en-us/library/ff477033(v=vs.110).aspx ist die Parallel Threading-Version der oben genannten Lösung, die eine Stapelsammlung verwendet und schneller ist.
Markus

0

Ich verwende den folgenden Code mit einem Formular, das zwei Schaltflächen enthält, eine zum Beenden und eine zum Starten. Ein Ordner-Browser-Dialog und ein Dialogfeld zum Speichern von Dateien. Der Code ist unten aufgeführt und funktioniert auf meinem System Windows 10 (64):

using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Directory_List
{

    public partial class Form1 : Form
    {
        public string MyPath = "";
        public string MyFileName = "";
        public string str = "";

        public Form1()
        {
            InitializeComponent();
        }    
        private void cmdQuit_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }    
        private void cmdGetDirectory_Click(object sender, EventArgs e)
        {
            folderBrowserDialog1.ShowDialog();
            MyPath = folderBrowserDialog1.SelectedPath;    
            saveFileDialog1.ShowDialog();
            MyFileName = saveFileDialog1.FileName;    
            str = "Folder = " + MyPath + "\r\n\r\n\r\n";    
            DirectorySearch(MyPath);    
            var result = MessageBox.Show("Directory saved to Disk!", "", MessageBoxButtons.OK);
                Application.Exit();    
        }    
        public void DirectorySearch(string dir)
        {
                try
            {
                foreach (string f in Directory.GetFiles(dir))
                {
                    str = str + dir + "\\" + (Path.GetFileName(f)) + "\r\n";
                }    
                foreach (string d in Directory.GetDirectories(dir, "*"))
                {

                    DirectorySearch(d);
                }
                        System.IO.File.WriteAllText(MyFileName, str);

            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }
}

-1
using System.IO;
using System.Text;
string[] filePaths = Directory.GetFiles(@"path", "*.*", SearchOption.AllDirectories);

Ihre Antwort fügt einer bereits vorhandenen Antwort mit der höchsten Bewertung nichts Neues hinzu.
Standardgebietsschema

1
Es ist auch falsch, da dies keine Verzeichnisse (wie in der angegebenen Frage angegeben) zurückgibt, sondern nur tatsächliche Dateien.
Alastair Maw

-1

Ein kleines bisschen einfach und langsam, aber es funktioniert !! Wenn Sie keinen Dateipfad angeben, verwenden Sie grundsätzlich den "fixPath". Dies ist nur ein Beispiel. Sie können den richtigen Dateityp suchen, den Sie möchten. Ich habe einen Fehler gemacht, als ich den Listennamen ausgewählt habe, da die "temporäre Dateiliste" die gesuchte Dateiliste ist also mach weiter .... und die "errorList" spricht für sich

 static public void Search(string path, string fileType, List<string> temporaryFileList, List<string> errorList)
    {

        List<string> temporaryDirectories = new List<string>();

        //string fix = @"C:\Users\" + Environment.UserName + @"\";
        string fix = @"C:\";
        string folders = "";
        //Alap útvonal megadása 
        if (path.Length != 0)
        { folders = path; }
        else { path = fix; }

        int j = 0;
        int equals = 0;
        bool end = true;

        do
        {

            equals = j;
            int k = 0;

            try
            {

                int foldersNumber = 
                Directory.GetDirectories(folders).Count();
                int fileNumber = Directory.GetFiles(folders).Count();

                if ((foldersNumber != 0 || fileNumber != 0) && equals == j)
                {

                    for (int i = k; k < 
                    Directory.GetDirectories(folders).Length;)
                    {

             temporaryDirectories.Add(Directory.GetDirectories(folders)[k]);
                        k++;
                    }

                    if (temporaryDirectories.Count == j)
                    {
                        end = false;
                        break;
                    }
                    foreach (string files in Directory.GetFiles(folders))
                    {
                        if (files != string.Empty)
                        {
                            if (fileType.Length == 0)
                            {
                                temporaryDirectories.Add(files);
                            }
                            else
                            {

                                if (files.Contains(fileType))
                                {
                                    temporaryDirectories.Add(files);

                                }
                            }
                        }
                        else
                        {
                            break;
                        }
                    }

                }

                equals++;

                for (int i = j; i < temporaryDirectories.Count;)
                {
                    folders = temporaryDirectories[i];
                    j++;
                    break;
                }

            }
            catch (Exception ex)
            {
                errorList.Add(folders);

                for (int i = j; i < temporaryDirectories.Count;)
                {
                    folders = temporaryDirectories[i];
                    j++;
                    break;
                }
            }
        } while (end);
    }

-1

Liste der Zeichenfolgen erstellen

    public static List<string> HTMLFiles = new List<string>();

 private void Form1_Load(object sender, EventArgs e)
        {

     HTMLFiles.AddRange(Directory.GetFiles(@"C:\DataBase", "*.txt"));
            foreach (var item in HTMLFiles)
            {
                MessageBox.Show(item);
            }

}

Dies erhält keine Unterverzeichnisse.
TidyDev

-1

dir / s / b . > results.txt

/ s = Unterordner / b = Ergebnisse tragen

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.