如何recursion列出在C#中的目录中的所有文件?
如何recursion列出C#中的目录和子目录中的所有文件?
本文涵盖了您所需要的一切。 除了search文件和比较名称之外,只需打印出名称即可。
它可以像这样修改:
static void DirSearch(string sDir) { try { foreach (string d in Directory.GetDirectories(sDir)) { foreach (string f in Directory.GetFiles(d)) { Console.WriteLine(f); } DirSearch(d); } } catch (System.Exception excpt) { Console.WriteLine(excpt.Message); } }
请注意,在.NET 4.0中,存在(假设)基于迭代器(而不是基于数组)的文件函数:
foreach (string file in Directory.EnumerateFiles( path, "*.*", SearchOption.AllDirectories)) { Console.WriteLine(file); }
此刻我会用下面的东西, 如果你没有访问一个单独的子目录,内置的recursion方法就容易中断…; Queue<string>
用法避免了太多的调用堆栈recursion,并且迭代器块避免了我们拥有巨大的数组。
static void Main() { foreach (string file in GetFiles(SOME_PATH)) { Console.WriteLine(file); } } static IEnumerable<string> GetFiles(string path) { Queue<string> queue = new Queue<string>(); queue.Enqueue(path); while (queue.Count > 0) { path = queue.Dequeue(); try { foreach (string subDir in Directory.GetDirectories(path)) { queue.Enqueue(subDir); } } catch(Exception ex) { Console.Error.WriteLine(ex); } string[] files = null; try { files = Directory.GetFiles(path); } catch (Exception ex) { Console.Error.WriteLine(ex); } if (files != null) { for(int i = 0 ; i < files.Length ; i++) { yield return files[i]; } } } }
Directory.GetFiles("C:\\", "*.*", SearchOption.AllDirectories)
至less在.NET 4.5中,这个版本要短得多,并且有额外的好处,可以评估包含在列表中的任何文件标准:
/// </remarks> 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; } }
使用像:
string folder = Config.TestInput(); string mask = folder + "*.*"; var list = UT.GetAllFiles(mask, (info) => Path.GetExtension(info.Name) == ".html").ToList(); Assert.AreNotEqual(0, list.Count); var lastQuarter = DateTime.Now.AddMonths(-3); list = UT.GetAllFiles(mask, (info) => info.CreationTime >= lastQuarter).ToList(); Assert.AreNotEqual(0, list.Count);
IEnumerable<string> GetFilesFromDir(string dir) => Directory.EnumerateFiles(dir).Concat( Directory.EnumerateDirectories(dir) .SelectMany(subdir => GetFilesFromDir(subdir)));
在Framework 2.0中,您可以使用(它列出根文件夹的文件,这是最受欢迎的答案):
static void DirSearch(string dir) { try { foreach (string f in Directory.GetFiles(dir)) Console.WriteLine(f); foreach (string d in Directory.GetDirectories(dir)) { Console.WriteLine(d); DirSearch(d); } } catch (System.Exception ex) { Console.WriteLine(ex.Message); } }
一些优秀的答案,但这些答案并没有解决我的问题。
一旦出现文件夹权限问题:“权限被拒绝”代码失败。 这是我用来解决“权限被拒绝”的问题:
private int counter = 0; private string[] MyDirectories = Directory.GetDirectories("C:\\"); private void ScanButton_Click(object sender, EventArgs e) { Thread MonitorSpeech = new Thread(() => ScanFiles()); MonitorSpeech.Start(); } private void ScanFiles() { string CurrentDirectory = string.Empty; while (counter < MyDirectories.Length) { try { GetDirectories(); CurrentDirectory = MyDirectories[counter++]; } catch { if (!this.IsDisposed) { listBox1.Invoke((MethodInvoker)delegate { listBox1.Items.Add("Access Denied to : " + CurrentDirectory); }); } } } } private void GetDirectories() { foreach (string directory in MyDirectories) { GetFiles(directory); } } private void GetFiles(string directory) { try { foreach (string file in Directory.GetFiles(directory, "*")) { listBox1.Invoke((MethodInvoker)delegate { listBox1.Items.Add(file); }); } } catch { listBox1.Invoke((MethodInvoker)delegate { listBox1.Items.Add("Access Denied to : " + directory); }); } }
希望这可以帮助别人。
一个简单而干净的解决scheme
/// <summary> /// Scans a folder and all of its subfolders recursively, and updates the List of files /// </summary> /// <param name="sFullPath">Full path of the folder</param> /// <param name="files">The list, where the output is expected</param> internal static void EnumerateFiles(string sFullPath, List<FileInfo> fileInfoList) { try { DirectoryInfo di = new DirectoryInfo(sFullPath); FileInfo[] files = di.GetFiles(); foreach (FileInfo file in files) fileInfoList.Add(file); //Scan recursively DirectoryInfo[] dirs = di.GetDirectories(); if (dirs == null || dirs.Length < 1) return; foreach (DirectoryInfo dir in dirs) EnumerateFiles(dir.FullName, fileInfoList); } catch (Exception ex) { Logger.Write("Exception in Helper.EnumerateFiles", ex); } }
}
如果您需要查找具有特定模式名称的文件(例如名称中某处包含特定string的XML文件),那么以下是我的angular度(基于Hernaldo的):
// call this like so: GetXMLFiles("Platypus", "C:\\"); public static List<string> GetXMLFiles(string fileType, string dir) { string dirName = dir; var fileNames = new List<String>(); try { foreach (string f in Directory.GetFiles(dirName)) { if ((f.Contains(fileType)) && (f.Contains(".XML"))) { fileNames.Add(f); } } foreach (string d in Directory.GetDirectories(dirName)) { GetXMLFiles(fileType, d); } } catch (Exception ex) { MessageBox.Show(ex.Message); } return fileNames; }
列出文件和文件夹以build模,自定义实现。
这将从您的开始目录开始创build所有文件和文件夹的完整列表。
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);
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(); }
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) { } }
简单而简单的解决scheme
string dir = @"D:\PATH"; DateTime from_date = DateTime.Now.Date; DateTime to_date = DateTime.Now.Date.AddHours(23); var files = Directory.EnumerateFiles(dir, "*.*",SearchOption.AllDirectories).Select(i=>new FileInfo(i)) .Where(file=>file.LastWriteTime >= from_date && file.LastWriteTime <= to_date); foreach(var fl in files) Console.WriteLine(fl.FullName);
我更喜欢使用DirectoryInfo,因为我可以得到FileInfo的,而不仅仅是string。
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();
如果需要的话,我也可以回到string。 (并仍然是未来的筛选器/ where-clause的东西certificate。
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();
请注意,如果你想扩展文件pipe理器,“ 。 ”是一个有效的search模式。
这里是B. Clay Shannon的代码对于excel文件不是静态的:
class ExcelSearcher { private List<string> _fileNames; public ExcelSearcher(List<string> filenames) { _fileNames = filenames; } public List<string> GetExcelFiles(string dir, List<string> filenames = null) { string dirName = dir; var dirNames = new List<string>(); if (filenames != null) { _fileNames.Concat(filenames); } try { foreach (string f in Directory.GetFiles(dirName)) { if (f.ToLower().EndsWith(".xls") || f.ToLower().EndsWith(".xlsx")) { _fileNames.Add(f); } } dirNames = Directory.GetDirectories(dirName).ToList(); foreach (string d in dirNames) { GetExcelFiles(d, _fileNames); } } catch (Exception ex) { //Bam } return _fileNames; }