使用.NET 3.0,我有下面的方法,它正确返回指定目录的所有文件和目录(和子目录)的集合。如果可能的话,我想把它简化为仅使用我非常熟悉的结构。具体来说,以下是我不清楚的事情:
1. IEnumerable<FileSystemInfo>: I'd like to return List<FileSystemInfo> instead
2. Stack<FileSystemInfo>: I'd list to use List<FileSystemInfo> instead.
3. yield return: I've never used this before
public static IEnumerable<FileSystemInfo> GetAllFilesAndDirectories ( string dir ) {
DirectoryInfo dirInfo = new DirectoryInfo( dir );
Stack<FileSystemInfo> stack = new Stack<FileSystemInfo>();
stack.Push( dirInfo );
while ( dirInfo != null || stack.Count > 0 ) {
FileSystemInfo fileSystemInfo = stack.Pop();
DirectoryInfo subDirectoryInfo = fileSystemInfo as DirectoryInfo;
if ( subDirectoryInfo != null ) {
yield return subDirectoryInfo;
foreach ( FileSystemInfo fsi in subDirectoryInfo.GetFileSystemInfos() ) {
stack.Push( fsi );
}
dirInfo = subDirectoryInfo;
} else {
yield return fileSystemInfo;
dirInfo = null;
}
}
}
可以说我应该对上面的代码感到满意,但这不是我今天拍摄的内容。
提前致谢
答案 0 :(得分:2)
这是我能想到的最短路:
static List<FileSystemInfo> GetAllFilesAndDirectories(string dir)
{
DirectoryInfo dirInfo = new DirectoryInfo(dir);
List<FileSystemInfo> allFilesAndDirectories = new List<FileSystemInfo>();
allFilesAndDirectories.AddRange(dirInfo.GetFiles("*", SearchOption.AllDirectories));
allFilesAndDirectories.AddRange(dirInfo.GetDirectories("*", SearchOption.AllDirectories));
return allFilesAndDirectories;
}
它将从给定路径开始返回所有级别的所有文件和目录的列表。它返回的顺序是所有文件,然后是所有目录。
答案 1 :(得分:1)
我相信您正在寻找现有方法GetFileSystemInfos(string,SearchOptions)。如果将AllDirectories指定为SearchOptions值,它将递归搜索传入的文件夹。
例如:
public static List<FileSystemInfo> GetAllFilesAndDirectories ( string dir ) {
DirectoryInfo info = new DirectoryInfo(dir);
FileSystemInfo[] all = info.GetFileSystemInfos("*", SearchOptions.AllDirectories);
return new List<FileSystemInfo>(all);
}
如果你想做很多事情,尽管你可以做到以下
public static List<FileSystemInfo> GetAllFilesAndDirectories ( string dir ) {
int i = 0;
List<DirectoryInfo> toProcess = new List<DirectoryInfo>();
List<FileSystemInfo> list = new List<FileSystemInfo>();
toProcess.Add(new DirectoryInfo(dir));
while ( i < toProcess.Count ) {
DirectoryInfo curDir = toProcess[i];
foreach ( FileSystemInfo curFile in curDir.GetFileSystemInfos() ) {
list.Add(curFile);
DirectoryInfo maybe = curFile as DirectoryInfo;
if ( maybe != null ) {
toProcess.Add(maybe);
}
i++;
}
return list;
}
FileSystemInfo[] all = info.GetFileSystemInfos("*", SearchOptions.AllDirectories);
return new List<FileSystemInfo>(all);
}
答案 2 :(得分:1)
public List<Object> GetFilesAndDirectories(string path)
{
List<Object> lst = new List<Object>();
string[] dirs = null;
try
{
dirs = Directory.GetDirectories(path);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
foreach (string d in dirs)
{
string[] files = null;
try
{
files = Directory.GetFiles(d);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
foreach (string f in files)
{
lst.Add(f);
}
lst.Add(d);
lst.AddRange(GetFilesAndDirectories(d));
}
return lst;
}
List<Object> stuff = GetFilesAndDirectories(someRoot);
答案 3 :(得分:0)
你曾经特别要求“愚蠢地”。我认为其他两个答案非常好,但是这是另一种方法,在开始级代码中使用更基本,易于理解的方式。
http://support.microsoft.com/kb/303974
修改
我知道这不是3.0,但它仍然是经过尝试,测试和易于理解的方式。
答案 4 :(得分:0)
如果你想要一个“初学者友好的方法”,我可以建议bobbymcr method。
但是,如果你想保留你的代码结构,我会重现我在your following question中发布的代码:
static IEnumerable<FileSystemInfo> GetAllFilesAndDirectories(string path)
{
string currentDirectory = "";
string[] files = Directory.GetFiles( // skip empty subfolders
path, "*.*", SearchOption.AllDirectories);
foreach (string file in files)
{
if(currentDirectory != Path.GetDirectoryName(file))
{
// First time in this directory: return it
currentDirectory = Path.GetDirectoryName(file);
yield return new DirectoryInfo(currentDirectory);
}
yield return new FileInfo(file);
}
}
答案 5 :(得分:0)
我认为从代码可读性的角度来看,最好的办法就是编写一个递归函数。递归函数是一个自我调用函数,直到它到达不需要调用任何其他函数的点。
为了说明,n的阶乘,写成n!并且定义为1 x 2 x 3 x ... x n(其中n是正整数)的数量可以很容易地以递归方式定义,如下所示。
public int factorial(int n)
{
if (n < 0)
{
throw new Exception("A factorial cannot be calculated for negative integers.");
}
if (n == 0 || n == 1)
{
// end condition, where we do not need to make a recursive call anymore
return 1;
}
else
{
// recursive call
return n * factorial(n - 1);
}
}
注意:0!和1!被定义为1。
同样,也可以递归地定义枚举给定路径下的所有文件和文件夹的方法。这是因为文件和文件夹具有递归结构。
因此,如下所述的方法可行:
public static List<FileSystemInfo> GetAllFilesAndFolders(string folder)
{
// NOTE : We are performing some basic sanity checking
// on the method's formal parameters here
if (string.IsNullOrEmpty(folder))
{
throw new ArgumentException("An empty string is not a valid path.", "folder");
}
if (!Directory.Exists(folder))
{
throw new ArgumentException("The string must be an existing path.", "folder");
}
List<FileSystemInfo> fileSystemInfos = new List<FileSystemInfo>();
try
{
foreach (string filePath in Directory.GetFiles(folder, "*.*"))
{
// NOTE : We will add a FileSystemInfo object for each file found
fileSystemInfos.Add(new FileInfo(filePath));
}
}
catch
{
// NOTE : We are swallowing all exceptions here
// Ideally they should be surfaced, and at least logged somewhere
// Most of these will be security/permissions related, i.e.,
// the Directory.GetFiles method will throw an exception if it
// does not have security privileges to enumerate files in a folder.
}
try
{
foreach (string folderPath in Directory.GetDirectories(folder, "*"))
{
// NOTE : We will add a FileSystemInfo object for each directory found
fileSystemInfos.Add(new DirectoryInfo(folderPath));
// NOTE : We will also add all FileSystemInfo objects found under
// each directory we find
fileSystemInfos.AddRange(GetAllFilesAndFolders(folderPath));
}
}
catch
{
// NOTE : We are swallowing all exceptions here
// Ideally they should be surfaced, and at least logged somewhere
// Most of these will be security/permissions related, i.e.,
// the Directory.GetDirectories method will throw an exception if it
// does not have security privileges to enumerate files in a folder.
}
return fileSystemInfos;
}
需要注意的一点是,此方法将“遍历”文件夹下的整个目录结构,并且在“走完”整个层次结构之前不会返回。因此,如果要找到很多对象,可能需要很长时间才能返回。
另外需要注意的是,使用Lambda表达式和扩展方法可以进一步提高此方法的可读性。
注意:使用Directory.GetFiles和Directory.GetDirectories来递归子文件夹的麻烦在于,如果抛出任何异常(例如,与安全权限相关),该方法将不返回任何内容,而手动递归则允许人们处理那些例外,仍然会得到一组文件。