如何在C#中递归列出目录中的所有文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/929276/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to recursively list all the files in a directory in C#?
提问by
How to recursively list all the files in a directory and child directories in C#?
如何在C#中递归列出目录和子目录中的所有文件?
采纳答案by John T
This articlecovers all you need. Except as opposed to searching the files and comparing names, just print out the names.
这篇文章涵盖了你需要的一切。除了搜索文件和比较名称之外,只需打印名称即可。
It can be modified like so:
可以这样修改:
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);
}
}
Added by barlop
由 barlop 添加
GONeale mentions that the above doesn't list the files in the current directory and suggests putting the file listing part outside the part that gets directories. The following would do that. It also includes a Writeline line that you can uncomment, that helps to trace where you are in the recursion that may help to show the calls to help show how the recursion works.
GONeale 提到上面没有列出当前目录中的文件,并建议将文件列表部分放在获取目录的部分之外。以下将做到这一点。它还包括您可以取消注释的 Writeline 行,它有助于跟踪您在递归中的位置,这可能有助于显示调用以帮助显示递归如何工作。
DirSearch_ex3("c:\aaa");
static void DirSearch_ex3(string sDir)
{
//Console.WriteLine("DirSearch..(" + sDir + ")");
try
{
Console.WriteLine(sDir);
foreach (string f in Directory.GetFiles(sDir))
{
Console.WriteLine(f);
}
foreach (string d in Directory.GetDirectories(sDir))
{
DirSearch_ex3(d);
}
}
catch (System.Exception excpt)
{
Console.WriteLine(excpt.Message);
}
}
回答by Marc Gravell
Note that in .NET 4.0 there are (supposedly) iterator-based (rather than array-based) file functions built in:
请注意,在 .NET 4.0 中,(据说)内置了基于迭代器(而不是基于数组)的文件函数:
foreach (string file in Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories))
{
Console.WriteLine(file);
}
At the moment I'd use something like below; the inbuilt recursive method breaks too easily if you don't have access to a single sub-dir...; the Queue<string>
usage avoids too much call-stack recursion, and the iterator block avoids us having a huge array.
目前我会使用类似下面的东西;如果您无权访问单个子目录,则内置递归方法很容易中断……;的Queue<string>
使用避免了过多的调用堆栈递归和迭代器块避免了一个巨大的数组我们。
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];
}
}
}
}
回答by John Kaster
In .NET 4.5, at least, there's this version that is much shorter and has the added bonus of evaluating any file criteria for inclusion in the list:
至少在 .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;
}
}
Use like this:
像这样使用:
var list = GetAllFiles(mask, (info) => Path.GetExtension(info.Name) == ".html").ToList();
回答by Rusty Nail
Some excellent answers but these answers did not solve my issue.
一些很好的答案,但这些答案并没有解决我的问题。
As soon as a folder permission issue arises: "Permission Denied" the code fails. This is what I used to get around the "Permission Denied" issue:
一旦出现文件夹权限问题:“权限被拒绝”,代码就会失败。这是我用来解决“权限被拒绝”问题的方法:
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); });
}
}
Hope this helps others.
希望这对其他人有帮助。
回答by Hernaldo Gonzalez
In Framework 2.0 you can use (It list files of root folder, it's best the most popular answer):
在 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);
}
}
回答by B. Clay Shannon
Here's my angle on it, based on Hernaldo's, if you need to find files with names of a certain pattern, such as XML files that somewhere in their name contain a particular string:
这是我的角度,基于 Hernaldo 的,如果您需要查找具有特定模式名称的文件,例如名称中某处包含特定字符串的 XML 文件:
// 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;
}
回答by Sardoan
Here is a version of B. Clay Shannon's code not static for excel-files:
这是 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;
}
回答by Pescuma
Directory.GetFiles("C:\", "*.*", SearchOption.AllDirectories)
回答by c_wiz_kid
Listing files and folders to model, custom implementation.
This creates a full listing of all files and folders starting from your start directory.
列出要建模的文件和文件夹,自定义实现。
这将创建从您的开始目录开始的所有文件和文件夹的完整列表。
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
}
Method:
方法:
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;
}
Usage:
用法:
var dir = new DirOrFileModel
{
Name = "C",
Location = @"C:\",
EntryType = EntryType.Directory
};
dir = DirSearch(dir);
回答by Goutham Padmanabha
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();
}