枚举长名称的文件和文件夹

时间:2014-05-23 06:53:59

标签: c#

如何枚举名称超过255个字符的文件和文件夹?

Directory.GetDirectories()Directory.GetFiles()会引发异常。


好吧,我找到了解决方案。

我的任务是找到文件夹中最长的路径。 这是我的解决方案: 1)定义我需要的一切

    public const uint FILE_ATTRIBUTE_DIRECTORY = 0x10;

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    public struct WIN32_FIND_DATA
    {
        public uint dwFileAttributes;
        public System.Runtime.InteropServices.ComTypes.FILETIME ftCreationTime;
        public System.Runtime.InteropServices.ComTypes.FILETIME ftLastAccessTime;
        public System.Runtime.InteropServices.ComTypes.FILETIME ftLastWriteTime;
        public uint nFileSizeHigh;
        public uint nFileSizeLow;
        public uint dwReserved0;
        public uint dwReserved1;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string cFileName;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)] public string cAlternateFileName;
    }

    public enum FINDEX_INFO_LEVELS
    { 
      FindExInfoStandard,
      FindExInfoBasic,
      FindExInfoMaxInfoLevel
    };

    public enum FINDEX_SEARCH_OPS { 
      FindExSearchNameMatch,
      FindExSearchLimitToDirectories,
      FindExSearchLimitToDevices
    };

    // dwAdditionalFlags:
    public const int FIND_FIRST_EX_CASE_SENSITIVE = 1;
    public const int FIND_FIRST_EX_LARGE_FETCH = 2;

    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern IntPtr FindFirstFileEx(
        string lpFileName,
        FINDEX_INFO_LEVELS fInfoLevelId,
        out WIN32_FIND_DATA lpFindFileData,
        FINDEX_SEARCH_OPS fSearchOp,
        IntPtr lpSearchFilter,
        int dwAdditionalFlags);

    [DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern bool FindNextFile(IntPtr hFindFile, out WIN32_FIND_DATA lpFindFileData);

    [DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern bool FindClose(IntPtr hFindFile);

2)功能本身

    private static int GetMaxPathLength(string path)
    {
        Console.WriteLine(path);
        if (path.StartsWith(@"\\?\") == false)
            path = @"\\?\" + path;

        WIN32_FIND_DATA findData;
        FINDEX_INFO_LEVELS findInfoLevel = FINDEX_INFO_LEVELS.FindExInfoStandard;
        int additionalFlags = 0;
        if (Environment.OSVersion.Version.Major >= 6)
        {
            findInfoLevel = FINDEX_INFO_LEVELS.FindExInfoBasic;
            additionalFlags = FIND_FIRST_EX_LARGE_FETCH;
        }

        IntPtr hFile = FindFirstFileEx(
            Path.Combine(path, "*.*"),
            findInfoLevel,
            out findData,
            FINDEX_SEARCH_OPS.FindExSearchNameMatch,
            IntPtr.Zero,
            additionalFlags);

        int maxRelativePathLength = 0;

        if (hFile.ToInt32() != -1)
        {
            do
            {
                int pathLength = 0;
                if ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)
                {
                    if (findData.cFileName.Equals(".") == false && findData.cFileName.Equals("..") == false)
                        pathLength = GetMaxPathLength(Path.Combine(path, findData.cFileName));
                }
                else
                {
                    pathLength = Path.Combine(path, findData.cFileName).Length;
                }

                if (maxRelativePathLength < pathLength)
                    maxRelativePathLength = pathLength;

            } while (FindNextFile(hFile, out findData));

            FindClose(hFile);
        }

        return maxRelativePathLength;
    }

0 个答案:

没有答案