如何枚举名称超过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;
}