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

发布于 2024-08-07 12:49:21 字数 1031 浏览 5 评论 0原文

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

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 未处理 消息=“堆栈为空。” 来源=“系统”

有什么想法如何修复吗?

This method works to get the files, directories and sub-directories and their contents, UNLESS one of the sub-directories happens to be empty.

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

}

The exception is:

System.InvalidOperationException was unhandled
Message="Stack empty."
Source="System"

Any ideas how to fix?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

冰雪梦之恋 2024-08-14 12:49:21

改变||到&&在你的 while 循环中。

Change || to && in your while loop.

云裳 2024-08-14 12:49:21

我为 您提出的问题添加了另一个答案不久前这将帮助您避免这种情况,因为您将使用与此处使用的代码完全不同(并且更易于阅读)的代码。

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

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

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

I added another answer to the question you asked a little while ago that will help you avoid this because you'd be using a completely different (and easier to read) bit of code than what you're using here.

However, to save you the time of looking, check out this article for a different way to recursively read files/directories.

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

I realize this isn't an answer to this specific question, but why spend time fixing a solution that's buggy when there's a perfectly viable solution that's easier to deal with?

笑咖 2024-08-14 12:49:21

我可以建议这段代码:

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)

If you Want a List<>, just call .ToList() method

I can suggest this code:

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

This will display:

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)

If you wanna a List<>, just call .ToList() method

只是一片海 2024-08-14 12:49:21
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;
            }
        }
    }
while (stack.Count > 0)

your while is working with stack.
even when you starting to collect from sub directory, the stack isn't empty.

but when you collecting from empty sub directory and sub directory at the end of directory list, your stack is empty, and there is no reason for continue to search.
the full fixed code is :

    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;
            }
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文