当存在空子目录时,调试GetAllFilesAndDirectories方法

时间:2009-10-10 04:36:45

标签: c# file directory

此方法用于获取文件,目录和子目录及其内容,除非其中一个子目录恰好为空。

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;
            }
        }

}

例外是:

System.InvalidOperationException未处理   消息=“堆栈空”。   源= “系统”

任何想法如何解决?

4 个答案:

答案 0 :(得分:1)

更改||和&amp;&amp;在你的while循环中。

答案 1 :(得分:0)

我添加了question you asked a little while ago的另一个答案,它可以帮助您避免这种情况,因为您使用的代码与您在此处使用的代码完全不同(且更容易阅读)。

但是,为了节省您的查看时间,请查看本文,了解以递归方式读取文件/目录的其他方法。

http://support.microsoft.com/kb/303974

我意识到这不是这个具体问题的答案,但是当有一个更容易处理的完全可行的解决方案时,为什么要花时间修复一个有问题的解决方案呢?

答案 2 :(得分:0)

我可以建议这段代码:

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);
    }
}

static void Main(string[] args)
{
    foreach (FileSystemInfo info in GetAllFilesAndDirectories(@"c:\intel"))
    {
        Console.WriteLine("{0} ({1})", info.FullName, info.Attributes);
    }
}

这将显示:

c:\intel\Logs (Directory)
c:\intel\Logs\IntelChipset.log (Archive)
c:\intel\Logs\IntelGFX.log (Archive)
c:\intel\Logs\IntelStor.log (Archive)
c:\intel\ExtremeGraphics\CUI\Resource (Directory)
c:\intel\ExtremeGraphics\CUI\Resource\igfxres.dll (Archive)

如果您想要List<>,请拨打.ToList()方法

答案 3 :(得分:0)

while (stack.Count > 0)

你正在使用堆栈。
即使你开始从子目录收集,堆栈也不是空的。

但是当您从目录列表末尾的空子目录和子目录中收集时,您的堆栈为空,并且没有理由继续搜索。
完整的固定代码是:

    public static IEnumerable<FileSystemInfo> GetAllFilesAndDirectories(string dir)
    {
        DirectoryInfo dirInfo = new DirectoryInfo(dir);
        Stack<FileSystemInfo> stack = new Stack<FileSystemInfo>();
        stack.Push(dirInfo);
        while (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);
                }
            }
            else
            {
                yield return fileSystemInfo;
            }
        }
    }