Getting files recursively: skip files/directories that cannot be read?

后端 未结 4 1432
感情败类
感情败类 2021-01-18 06:11

I want to get all of the files in a directory in an array (including the files in subfolders)

string[] filePaths = Directory.GetFiles(@\"c:\\\",SearchOption.         


        
相关标签:
4条回答
  • 2021-01-18 06:23

    try this :

    DirectoryInfo directory = new DirectoryInfo(@"c:\");
            DirectoryInfo[] folders = directory.GetDirectories("*", SearchOption.AllDirectories);
    
            List<string> files = new List<string>();
            foreach (DirectoryInfo info in folders)
            {
                foreach (FileInfo file in info.GetFiles())
                {
                    files.Add(file.Name);
                }
            }
    
    0 讨论(0)
  • 2021-01-18 06:32

    or try this one :

            DirectoryInfo dirs = new DirectoryInfo(@"c:\");
            List<string> filenames = (from i in dirs.GetFiles("*", SearchOption.AllDirectories)
                                      select i.Name).ToList();
    

    or file names without extension :

            DirectoryInfo dirs = new DirectoryInfo@"c:\");
            List<string> filenames = (from i in dirs.GetFiles("*", SearchOption.AllDirectories)
                                      select System.IO.Path.GetFileNameWithoutExtension(i.Name)).ToList();
    
    0 讨论(0)
  • 2021-01-18 06:36

    You'd probably have to do a bit more typing yourself then, and write a directory walker like this one:

        public static string[] FindAllFiles(string rootDir) {
            var pathsToSearch = new Queue<string>();
            var foundFiles = new List<string>();
    
            pathsToSearch.Enqueue(rootDir);
    
            while (pathsToSearch.Count > 0) {
                var dir = pathsToSearch.Dequeue();
    
                try {
                    var files = Directory.GetFiles(dir);
                    foreach (var file in Directory.GetFiles(dir)) {
                        foundFiles.Add(file);
                    }
    
                    foreach (var subDir in Directory.GetDirectories(dir)) {
                        pathsToSearch.Enqueue(subDir);
                    }
    
                } catch (Exception /* TODO: catch correct exception */) {
                    // Swallow.  Gulp!
                }
            }
    
            return foundFiles.ToArray();
        }
    
    0 讨论(0)
  • 2021-01-18 06:38

    Directory.GetFiles can't skip directory symbol links which often cause loops and then exceptions.

    So based on @iks's answer and Check if a file is real or a symbolic link, here is a version that deliver the result on the go like Directory.EnumerateFiles does:

        public static IEnumerable<string> FindAllFiles(string rootDir)
        {
            var pathsToSearch = new Queue<string>();
    
    
            pathsToSearch.Enqueue(rootDir);
    
            while (pathsToSearch.Count > 0)
            {
                var dir = pathsToSearch.Dequeue();
                var foundFiles = new List<string>();
                try
                {
                    foreach (var file in Directory.GetFiles(dir))
                        foundFiles.Add(file);
    
                    foreach (var subDir in Directory.GetDirectories(dir))
                    {
                        //comment this if want to follow symbolic link
                        //or follow them conditionally
                        if (IsSymbolic(subDir)) continue;
                        pathsToSearch.Enqueue(subDir);
                    }
                }
                catch (Exception) {//deal with exceptions here
                }
                foreach (var file in foundFiles) yield return file;
            } 
    
    
        }
    
        static private bool IsSymbolic(string path)
        {
            FileInfo pathInfo = new FileInfo(path);
            return pathInfo.Attributes.HasFlag(System.IO.FileAttributes.ReparsePoint);
        }
    
        static public void test()
        {
            string root = @"D:\root";
            foreach (var fn in FindAllFiles(root)
                .Where(x=>
                true    //filter condition here
                ))
            {
                Debug.WriteLine(fn);
            }
        }
    
    0 讨论(0)
提交回复
热议问题