Buat daftar semua file dan direktori dalam direktori + subdirektori


109

Saya ingin membuat daftar setiap file dan direktori yang ada dalam direktori dan subdirektori dari direktori itu. Jika saya memilih C: \ sebagai direktori, program akan mendapatkan setiap nama dari setiap file dan folder pada hard drive yang dapat diaksesnya.

Daftar mungkin terlihat seperti ini

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

Jelajahi namespace System.IO untuk kelas dan metode yang mungkin membantu Anda.
Lucero

Lihat pertanyaan ini , dan hilangkan bagian di mana dia mencocokkan pola.
dasblinkenlight

Jawaban:


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

dimana *.*pola untuk mencocokkan file

Jika Direktori juga diperlukan, Anda dapat melakukannya seperti ini:

 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
Tidak akan benar-benar berfungsi ... Lsit<>kelas? Apa yang dikembalikan GetFiles? Dan bagaimana dengan nama direktori yang juga diminta?
Lucero

1
The GetFilesMetode mengembalikan sebuah array string.
Guffa

sebenarnya ... Anda benar ... Saya belajar Qt sekitar 2 hari yang lalu dan salah sedikit
Ruslan F.

Ini mungkin berhasil, tetapi sering gagal dengan UnauthorizedAccessException. Bagaimana mencari hanya direktori yang dapat diaksesnya?
derp_in_mouth

artinya dalam sistem Anda, aplikasi ini tidak memiliki cukup izin
Ruslan F.

50

Directory.GetFileSystemEntriesada di .NET 4.0+ dan mengembalikan file dan direktori. Sebut saja seperti ini:

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

Perhatikan bahwa ini tidak akan mengatasi upaya untuk membuat daftar konten subdirektori yang tidak Anda miliki aksesnya (UnauthorizedAccessException), tetapi ini mungkin cukup untuk kebutuhan Anda.


3
Sejauh ini, inilah jawaban terbaik di sini. Itu mendapatkan semua file dan folder dalam satu baris kode, yang tidak dilakukan oleh yang lain.
Steve Smith

15

Gunakan GetDirectoriesdan GetFilesmetode untuk mendapatkan folder dan file.

Gunakan juga untuk mendapatkan folder dan file di subfolder.SearchOption AllDirectories


Gunakan Substring untuk memotong bagian kiri nama. :)
Lucero

@ Lucero Bagaimana dan mengapa Anda melakukan itu? Pathmenawarkan metode yang lebih andal.
Gusdor

@Gusdor Jangan ragu untuk menyarankan cara yang lebih cocok menggunakan Pathuntuk menghapus bagian kiri jalan tetap, misalnya `C:` dalam contoh yang diberikan.
Lucero

@ Lucero, komentar saya diutarakan dengan buruk. 'Gunakan substring' tidak memberi tahu saya banyak dan saya harus terjebak di linqpad untuk mendapatkan solusi yang bagus. Misalnya, apa parameternya? Apakah Anda akan path.SubString(2)menghapus huruf drive dan titik dua secara naif? Bagaimana jika direktori tersebut adalah jaringan bersama? Saya sarankan Pathsebagai metode yang andal karena dapat memberikan banyak barang di area ini. Dalam hal ini, Anda boleh menulis filePath.Substring(Path.GetPathRoot(filePath).Length). Ya, ini menggunakan Substring karena ini yang paling ringkas.
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
Ini akan meningkatkan jawaban Anda jika Anda dapat menambahkan sedikit penjelasan tentang fungsi kode tersebut.
Alex

Ini berjalan secara rekursif melalui direktori dan mencetak nama file atau nama direktori. Untuk setiap direktori dalam itu memanggil fungsi yang sama. Untuk informasi lebih lanjut: stackoverflow.com/questions/929276/…
I.Step

3

Saya khawatir, GetFilesmetode ini mengembalikan daftar file tetapi bukan direktori. Daftar di pertanyaan meminta saya bahwa hasilnya harus menyertakan folder juga. Jika Anda ingin daftar yang lebih disesuaikan, Anda dapat mencoba menelepon GetFilesdan GetDirectoriessecara rekursif. Coba ini:

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);
}

Tip: Anda dapat menggunakan FileInfodan DirectoryInfokelas jika Anda perlu memeriksa atribut tertentu.


1

Anda dapat menggunakan FindFirstFile yang mengembalikan sebuah pegangan dan kemudian secara rekursif memanggil fungsi yang memanggil FindNextFile. Ini adalah pendekatan yang baik karena struktur yang direferensikan akan diisi dengan berbagai data seperti alternativeName, lastTmeCreated, modified, atribut dll.

Tetapi saat Anda menggunakan .net framework, Anda harus memasuki area yang tidak dikelola.


1

Beberapa versi yang ditingkatkan dengan max lvl untuk turun di direktori dan opsi untuk mengecualikan folder:

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+"  ");
        }
    }
  }
}

direktori masukan:

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

output dari fungsi (konten folder5 dikecualikan karena batas lvl dan konten folder3 dikecualikan karena berada dalam array excludedFolders):

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

0

Jika Anda tidak memiliki akses ke subfolder di dalam pohon direktori, Directory.GetFiles berhenti dan menampilkan pengecualian yang menghasilkan nilai null dalam string penerima [].

Di sini, lihat jawaban ini https://stackoverflow.com/a/38959208/6310707

Ini mengelola pengecualian di dalam loop dan terus bekerja sampai seluruh folder dilalui.


0

cara yang logis dan teratur:

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);
            }
        }
    }
}
}

Bisakah Anda memberikan penjelasan atau komentar sebaris, apa fungsi kode Anda?
MarthyM

tentu saja, melakukannya, tetapi harus cukup jelas, ini adalah rekursi perulangan sederhana melalui semua direktori dan file
Sascha

0

Berikut contoh tercepat (tidak diparalelkan) daftar file dan sub-folder dalam pengecualian penanganan pohon direktori. Akan lebih cepat jika menggunakan Directory.EnumerateDirectories menggunakan SearchOption.AllDirectories untuk menghitung semua direktori, tetapi metode ini akan gagal jika mengenai UnauthorizedAccessException atau PathTooLongException.

Menggunakan tipe kumpulan Tumpukan generik, yang merupakan tumpukan terakhir masuk pertama keluar (LIFO) dan tidak menggunakan rekursi. Dari https://msdn.microsoft.com/en-us/library/bb513869.aspx , memungkinkan Anda untuk menghitung semua sub-direktori dan file dan menangani pengecualian tersebut secara efektif.

    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);
        }
    }
}

Menggunakan Tasks untuk file dan direktori dalam jumlah besar?
PreguntonCojoneroCabrón

msdn.microsoft.com/en-us/library/ff477033(v=vs.110).aspx adalah versi Parallel Threading dari solusi di atas menggunakan kumpulan tumpukan dan lebih cepat.
Markus

0

Saya menggunakan kode berikut dengan formulir yang memiliki 2 tombol, satu untuk keluar dan yang lainnya untuk memulai. Dialog browser folder dan dialog simpan file. Kode tercantum di bawah ini dan berfungsi di sistem saya Windows10 (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);
            }
        }
    }
}

0

Dengan ini Anda bisa menjalankannya dan memilih sub folder saat konsol dijalankan

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using data.Patcher; // The patcher XML
namespace PatchBuilder
{
class Program
{
    static void Main(string[] args)
    {
        string patchDir;
        if (args.Length == 0)
        {
            Console.WriteLine("Give the patch directory in argument");
            patchDir = Console.ReadLine();
        }
        else
        {
            patchDir = args[0];
        }

        if (File.Exists(Path.Combine(patchDir, "patch.xml")))
            File.Delete(Path.Combine(patchDir, "patch.xml"));

        var files = Directory.EnumerateFiles(patchDir, "*", SearchOption.AllDirectories).OrderBy(p => p).ToList();

        foreach (var file in files.Where(file => file.StartsWith("patch\\Resources")).ToArray())
        {
            files.Remove(file);
            files.Add(file);
        }

        var tasks = new List<MetaFileEntry>();
        using (var md5Hasher = MD5.Create())
        {
            for (int i = 0; i < files.Count; i++)
            {
                var file = files[i];

                if ((File.GetAttributes(file) & FileAttributes.Hidden) != 0)
                    continue;

                var content = File.ReadAllBytes(file);
                var md5Hasher2 = MD5.Create();

                var task =
                    new MetaFileEntry
                    {
                        LocalURL = GetRelativePath(file, patchDir + "\\"),
                        RelativeURL = GetRelativePath(file, patchDir + "\\"),
                        FileMD5 = Convert.ToBase64String(md5Hasher2.ComputeHash(content)),
                        FileSize = content.Length,
                    };

                md5Hasher2.Dispose();

                var pathBytes = Encoding.UTF8.GetBytes(task.LocalURL.ToLower());
                md5Hasher.TransformBlock(pathBytes, 0, pathBytes.Length, pathBytes, 0);
                if (i == files.Count - 1)
                    md5Hasher.TransformFinalBlock(content, 0, content.Length);
                else
                    md5Hasher.TransformBlock(content, 0, content.Length, content, 0);

                tasks.Add(task);
                Console.WriteLine(@"Add " + task.RelativeURL);
            }

            var patch = new MetaFile
            {
                Tasks = tasks.ToArray(),
                FolderChecksum = BitConverter.ToString(md5Hasher.Hash).Replace("-", "").ToLower(),
            };


            //XmlUtils.Serialize(Path.Combine(patchDir, "patch.xml"), patch);
            Console.WriteLine(@"Created Patch in {0} !", Path.Combine(patchDir, "patch.xml"));
        }

        Console.Read();
    }

    static string GetRelativePath(string fullPath, string relativeTo)
    {
        var foldersSplitted = fullPath.Split(new[] { relativeTo.Replace("/", "\\").Replace("\\\\", "\\") }, StringSplitOptions.RemoveEmptyEntries); // cut the source path and the "rest" of the path

        return foldersSplitted.Length > 0 ? foldersSplitted.Last() : ""; // return the "rest"
    }
}
}

dan ini patchar untuk ekspor XML

using System.Xml.Serialization;

namespace data.Patcher
{
    public class MetaFile
    {

        [XmlArray("Tasks")]
        public MetaFileEntry[] Tasks
        {
            get;
            set;
        }

        [XmlAttribute("checksum")]
        public string FolderChecksum
        {
            get;
            set;
        }
    }
}

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

Jawaban Anda tidak menambahkan sesuatu yang baru ke jawaban pilihan teratas yang sudah ada.
lokal default

1
Ini juga salah, karena ini tidak mengembalikan direktori apa pun (seperti pertanyaan yang ditentukan), hanya file yang sebenarnya.
Alastair Maw

-1

Sebuah littlebit sederhana dan lambat tapi bekerja !! jika Anda tidak memberikan jalur file pada dasarnya gunakan "fixPath" ini hanya contoh .... Anda dapat mencari fileType yang benar apa yang Anda inginkan, saya melakukan kesalahan saat memilih nama daftar karena "temporaryFileList adalah daftar file yang dicari jadi lanjutkan itu .... dan "errorList" berbicara untuk dirinya sendiri

 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

Buat Daftar String

    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);
            }

}

Ini tidak mendapatkan sub direktori.
TidyDev

-1

dir / s / b .> results.txt

/ s = subfolder / b = menanggung hasil

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.