列出目录+子目录中的所有文件和目录


109

我想列出目录中包含的每个文件和目录以及该目录的子目录。如果我选择C:\作为目录,则程序将获取其有权访问的硬盘驱动器上每个文件和文件夹的每个名称。

列表可能看起来像

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

浏览System.IO命名空间,以获取可能对您有所帮助的方法
Lucero 2012年

找出这个问题,并将其与模式匹配的部分删除。
dasblinkenlight 2012年

Answers:


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

*.*匹配文件的模式在哪里

如果还需要目录,则可以这样:

 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
真的不会Lsit<>上课吗?GetFiles返回什么?以及同样要求的目录名称又如何呢?
Lucero 2012年

1
GetFiles方法返回一个字符串数组。
Guffa 2012年

实际上...您是对的... 2天前我正在学习Qt abaout,但被误会了
Ruslan F.

这可能有效,但通常会失败,并显示UnauthorizedAccessException。如何仅搜索它可以访问的目录?
derp_in_mouth 2012年

这意味着在您的系统中,此应用没有足够的权限
Ruslan F.

50

Directory.GetFileSystemEntries在.NET 4.0+中存在,并返回文件和目录。这样称呼它:

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

请注意,它无法应付列出您无权访问的子目录的内容的尝试(UnauthorizedAccessException),但这可能足以满足您的需求。


3
这是到目前为止最好的答案。它在一行代码中获取所有文件和文件夹,而其他任何一个都不行。
史蒂夫·史密斯

15

使用GetDirectoriesGetFiles方法获取文件夹和文件。

也可以使用来获取子文件夹中的文件夹和文件。SearchOption AllDirectories


使用Substring切断名称的左侧部分。:)
Lucero 2012年

@Lucero您如何以及为什么要这样做?Path提供更可靠的方法。
古斯多

@Gusdor随意建议使用一种更合适的方法来Path删除路径的固定左侧部分,例如,在给定的示例中为`C:`。
卢塞罗

@Lucero我的评论用词不好。“使用子字符串”并不能告诉我很多,我必须陷入linqpad才能得到一个不错的解决方案。例如,参数是什么?您要path.SubString(2)天真的删除驱动器号和冒号吗?如果目录是网络共享怎么办?我建议将其Path作为一种可靠的方法,因为它可以在此区域提供大量的东西。在这种情况下,您可以编写filePath.Substring(Path.GetPathRoot(filePath).Length)。是的,因为它最简洁,所以使用了子字符串。
古斯多

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
如果您可以添加一些有关代码功能的说明,将会改善您的答案。
Alex

它以递归方式遍历目录并打印文件名或目录名。对于每个内部目录,它调用相同的函数。欲了解更多信息: stackoverflow.com/questions/929276/...
I.Step

3

恐怕该GetFiles方法返回文件列表,但不返回目录。问题中的列表提示我结果也应包括文件夹。如果您想了解更多自定义列表,您可以尝试调用GetFilesGetDirectories递归。试试这个:

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

提示:如果需要检查任何特定属性,则可以使用FileInfoDirectoryInfo类。


1

您可以使用FindFirstFile返回一个句柄,然后递归地校准一个调用FindNextFile的函数。这是一个很好的方法,因为所引用的结构将充满各种数据,例如AlternativeName,lastTmeCreated,modified,attributes等

但是,在使用.net框架时,您将不得不进入非托管区域。


1

带有max lvl的某些改进版本可以在目录中找到,并可以选择排除文件夹:

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

输入目录:

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

该函数的输出(由于lvl限制,不包括folder5的内容,并且不包括folder3的内容,因为它位于excludeFolders数组中):

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

0

如果您无权访问目录树中的子文件夹,则Directory.GetFiles停止并引发异常,从而导致接收字符串[]中的值为空。

在这里,看到这个答案 https://stackoverflow.com/a/38959208/6310707

它管理循环内的异常并继续工作,直到遍历整个文件夹为止。


0

逻辑和有序的方式:

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

您能否提供解释或在线注释,您的代码是做什么的?
MarthyM '17

当然可以,但是这应该可以自我解释,它是对所有目录和文件的简单循环递归
Sascha

0

下面的例子最快(非并行)的方式列出目录树中的文件和子文件夹,以处理异常。使用Directory.EnumerateDirectories和SearchOption.AllDirectories枚举所有目录会更快,但是如果遇到UnauthorizedAccessException或PathTooLongException,则此方法将失败。

使用通用堆栈集合类型,该类型是后进先出(LIFO)堆栈,并且不使用递归。从https://msdn.microsoft.com/zh-cn/library/bb513869.aspx,您可以枚举所有子目录和文件并有效地处理这些异常。

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

使用Tasks处理大量文件和目录?
PreguntonCojoneroCabrón

msdn.microsoft.com/zh-cn/library/ff477033(v=vs.110).aspx是上述解决方案的并行线程版本,使用堆栈收集且速度更快。
马库斯

0

我将以下代码与具有2个按钮的窗体一起使用,一个用于退出,另一个用于启动。文件夹浏览器对话框和保存文件对话框。代码在下面列出,并且可以在我的系统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);
            }
        }
    }
}

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

您的答案不会为已经存在的最高投票答案添加任何新内容。
默认语言环境

1
这也是错误的,因为它不返回任何目录(如指定的问题),仅返回实际文件。
Alastair花胶2015年

-1

一点点简单而缓慢但可以工作!如果您根本不使用“ fixPath”给文件路径,这只是示例...。您可以搜索所需的正确文件类型,选择列表名称时出现了错误,因为“ temporaryFileList是搜索到的文件列表”因此,继续进行下去。...而“ errorList”就是不言而喻的

 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

创建字符串列表

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

}

这不会获得子目录。
TidyDev

-1

目录/ s / b > results.txt

/ s =子文件夹/ b =结果

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.