如何递归列出所有文件在一个目录和子目录在c# ?


当前回答

一个非常简单的解决方案,返回一个文件列表。

    public static List<string> AllFilesInFolder(string folder)
    {
        var result = new List<string>();

        foreach (string f in Directory.GetFiles(folder))
        {
            result.Add(f);
        }

        foreach (string d in Directory.GetDirectories(folder))
        {
            result.AddRange(AllFilesInFolder(d));
        }

        return result;
    }

其他回答

列出要建模的文件和文件夹,自定义实现。 这将创建从起始目录开始的所有文件和文件夹的完整列表。

public class DirOrFileModel
    {
        #region Private Members

        private string _name;
        private string _location;
        private EntryType _entryType;

        #endregion

        #region Bindings

        public string Name
        {
            get { return _name; }
            set
            {
                if (value == _name) return;
                _name = value;
            }
        }

        public string Location
        {
            get { return _location; }
            set
            {
                if (value == _location) return;
                _location = value;
            }
        }

        public EntryType EntryType
        {
            get { return _entryType; }
            set
            {
                if (value == _entryType) return;
                _entryType = value;
            }
        }

        public ObservableCollection<DirOrFileModel> Entries { get; set; }

        #endregion

        #region Constructor

        public DirOrFileModel()
        {
            Entries = new ObservableCollection<DirOrFileModel>();
        }

        #endregion
    }

    public enum EntryType
    {
        Directory = 0,
        File = 1
    }

方法:

 static DirOrFileModel DirSearch(DirOrFileModel startDir)
        {
            var currentDir = startDir;
            try
            {
                foreach (string d in Directory.GetDirectories(currentDir.Location))
                {
                    var newDir = new DirOrFileModel
                    {
                        EntryType = EntryType.Directory,
                        Location = d,
                        Name = Path.GetFileName(d)
                    };
                    currentDir.Entries.Add(newDir);

                    DirSearch(newDir);
                }

                foreach (string f in Directory.GetFiles(currentDir.Location))
                {
                    var newFile = new DirOrFileModel
                    {
                        EntryType = EntryType.File,
                        Location = f,
                        Name = Path.GetFileNameWithoutExtension(f)
                    };
                    currentDir.Entries.Add(newFile);
                }

            }
            catch (Exception excpt)
            {
                Console.WriteLine(excpt.Message);
            }
            return startDir;
        }

用法:

var dir = new DirOrFileModel
            {
                Name = "C",
                Location = @"C:\",
                EntryType = EntryType.Directory
            };

            dir = DirSearch(dir);
private void GetFiles(DirectoryInfo dir, ref List<FileInfo> files)
{
    try
    {
        files.AddRange(dir.GetFiles());
        DirectoryInfo[] dirs = dir.GetDirectories();
        foreach (var d in dirs)
        {
            GetFiles(d, ref files);
        }
    }
    catch (Exception e)
    {

    }
}

至少在。net 4.5中,有这样一个版本,它要短得多,并且有额外的好处,可以评估包含在列表中的任何文件标准:

public static IEnumerable<string> GetAllFiles(string path, 
                                              Func<FileInfo, bool> checkFile = null)
{
    string mask = Path.GetFileName(path);
    if (string.IsNullOrEmpty(mask)) mask = "*.*";
    path = Path.GetDirectoryName(path);
    string[] files = Directory.GetFiles(path, mask, SearchOption.AllDirectories);

    foreach (string file in files)
    {
        if (checkFile == null || checkFile(new FileInfo(file)))
            yield return file;
    }
}

像这样使用:

var list = GetAllFiles(mask, (info) => Path.GetExtension(info.Name) == ".html").ToList();

我更喜欢使用DirectoryInfo,因为我可以得到FileInfo的,而不仅仅是字符串。

        string baseFolder = @"C:\temp";
        DirectoryInfo di = new DirectoryInfo(baseFolder);

        string searchPattern = "*.xml";

        ICollection<FileInfo> matchingFileInfos = di.GetFiles(searchPattern, SearchOption.AllDirectories)
            .Select(x => x)
            .ToList();

我这样做的情况下,在未来我需要未来过滤..基于FileInfo的属性。

        string baseFolder = @"C:\temp";
        DirectoryInfo di = new DirectoryInfo(baseFolder);

        string searchPattern = "*.xml";

        ICollection<FileInfo> matchingFileInfos = di.GetFiles(searchPattern, SearchOption.AllDirectories)
            .Where(x => x.LastWriteTimeUtc < DateTimeOffset.Now)
            .Select(x => x)
            .ToList();

如果需要,我也可以求助于字符串。(仍然是未来证明过滤器/where-clause子句的东西。

        string baseFolder = @"C:\temp";
        DirectoryInfo di = new DirectoryInfo(baseFolder);

        string searchPattern = "*.xml";

        ICollection<string> matchingFileNames = di.GetFiles(searchPattern, SearchOption.AllDirectories)
            .Select(x => x.FullName)
            .ToList();

请注意,如果您想通过扩展文件,“.”是一个有效的搜索模式。

static void Main(string[] args)
        {
            string[] array1 = Directory.GetFiles(@"D:\");
            string[] array2 = System.IO.Directory.GetDirectories(@"D:\");
            Console.WriteLine("--- Files: ---");
            foreach (string name in array1)
            {
                Console.WriteLine(name);
            }
            foreach (string name in array2)
            {
                Console.WriteLine(name);
            }
                  Console.ReadLine();
        }