如果目录不包含子文件夹,则显示所有可访问的目录为空

时间:2013-09-01 14:36:45

标签: c#

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using Microsoft.Win32.SafeHandles;

namespace Demo
{
    public class Program
    {
        private void run()
        {
            string root = "C:\\";

            foreach (var folder in FolderEnumerator.EnumerateFoldersRecursively(root))
                Console.WriteLine(folder);
        }

        private static void Main()
        {
            new Program().run();
        }
    }

    public static class FolderEnumerator
    {
        public static IEnumerable<string> EnumerateFoldersRecursively(string root)
        {
            foreach (var folder in EnumerateFolders(root))
            {
                yield return folder;

                foreach (var subfolder in EnumerateFoldersRecursively(folder))
                    yield return subfolder;
            }
        }

        public static IEnumerable<string> EnumerateFolders(string root)
        {
            WIN32_FIND_DATA findData;
            string spec = Path.Combine(root, "*");

            using (SafeFindHandle findHandle = FindFirstFile(spec, out findData))
            {
                if (!findHandle.IsInvalid)
                {
                    do
                    {
                        if ((findData.cFileName != ".") && (findData.cFileName != ".."))  // Ignore special "." and ".." folders.
                        {
                            if ((findData.dwFileAttributes & FileAttributes.Directory) != 0)
                            {
                                yield return Path.Combine(root, findData.cFileName);
                            }
                        }
                    }
                    while (FindNextFile(findHandle, out findData));
                }
            }
        }

        internal sealed class SafeFindHandle: SafeHandleZeroOrMinusOneIsInvalid
        {
            [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]

            public SafeFindHandle(): base(true)
            {
            }

            protected override bool ReleaseHandle()
            {
                if (!IsInvalid && !IsClosed)
                {
                    return FindClose(this);
                }

                return (IsInvalid || IsClosed);
            }

            protected override void Dispose(bool disposing)
            {
                if (!IsInvalid && !IsClosed)
                {
                    FindClose(this);
                }

                base.Dispose(disposing);
            }
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct FILETIME
        {
            public uint dwLowDateTime;
            public uint dwHighDateTime;

            public long ToLong()
            {
                return dwLowDateTime + ((long)dwHighDateTime) << 32;
            }
        };

        [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]

        internal struct WIN32_FIND_DATA
        {
            public FileAttributes dwFileAttributes;
            public FILETIME       ftCreationTime;
            public FILETIME       ftLastAccessTime;
            public FILETIME       ftLastWriteTime;
            public int            nFileSizeHigh;
            public int            nFileSizeLow;
            public int            dwReserved0;
            public int            dwReserved1;

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=MAX_PATH)]
            public string cFileName;

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=MAX_ALTERNATE)]
            public string cAlternate;
        }

        [DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Unicode)]
        private static extern SafeFindHandle FindFirstFile(string lpFileName, out WIN32_FIND_DATA lpFindFileData);

        [DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Unicode)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool FindNextFile(SafeHandle hFindFile, out WIN32_FIND_DATA lpFindFileData);

        [DllImport("kernel32.dll", SetLastError=true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool FindClose(SafeHandle hFindFile);

        private const int MAX_PATH = 260;
        private const int MAX_ALTERNATE = 14;
    }
}

此解决方案驱动器上的所有可访问目录。 问题是如果文件夹不包含子文件夹,则返回集合为空 我需要改变什么来修复它? (我使用EnumerateFoldersRecursively方法接收我的root下的所有目录,我也想接收到根文件夹)

0 个答案:

没有答案
相关问题