我正在开发一个应用程序,该应用程序遍历某些目录中的每个文件,并对这些文件执行一些操作。除其他外,我必须检索文件大小和修改此文件的日期。
某些文件全名(目录+文件名)太长,我无法使用.NET Framework FileInfo,它被限制为MAX_PATH(260个字符)。许多Web来源建议通过P / Invoke使用本机Win32函数来访问名称过长的文件。
FileInfo
MAX_PATH
当前,Win32函数似乎会出现完全相同的问题。例如对于GetFileAttributesEx(270字节)的路径(kernel32.dll)失败,并出现Win32错误3 ERROR_PATH_NOT_FOUND。
GetFileAttributesEx
可以从Notepad2成功打开相同的文件,并使用Windows资源管理器成功显示该文件(例如,由于259个字符的限制¹,Visual Studio 2010无法打开它)。
文件路径为270个字符长时,我该怎么办才能访问文件?
笔记:
删除或忽略文件路径长度超过259个字符的文件不是解决方案。
我仅在寻找与Unicode兼容的解决方案。
该应用程序将在Windows 2008 / Vista或更高版本(安装了.NET Framework 4)下运行。
¹令人惊讶的是,Microsoft Word 2007失败,抱怨没有软盘驱动器的计算机上的“软盘太小”,或者当剩余4 GB的RAM时抱怨“ RAM内存不足”,或者最后是“需要更新防病毒软件”。他们是否会停止一天至少在诸如Microsoft Office之类的关键产品中显示如此愚蠢的毫无意义的错误?
.NET 4.6.2解决方案
使用此处 \\?\C:\Verrrrrrrrrrrry long path 描述的语法。
\\?\C:\Verrrrrrrrrrrry long path
.NET Core解决方案
之所以起作用,是因为该框架为您添加了长路径语法。
.NET 4.6.2之前的解决方案
还可以 通过P / Invoke 使用长路径语法 和Win32 API函数的Unicode版本。 从命名文件,路径和命名空间:
Windows API具有许多功能,它们也具有Unicode版本,以允许使用扩展长度的路径,最大总路径长度为32,767个字符。这种类型的路径由用反斜杠分隔的组件组成,每个反斜杠都取决于GetVolumeInformation函数的lpMaximumComponentLength参数中返回的值(该值通常为255个字符)。 要指定扩展长度的路径,请使用\\?\前缀。例如,\\?\D:\very long path。
\\?\
\\?\D:\very long path
阅读此Microsoft支持页面也可能很有趣。
BCL团队博客的Kim Hamilton在.NET中的Long Paths中进行了非常广泛的解释,列出了处理这些路径的一些障碍,他声称这是.NET仍不直接支持此语法的原因:
我们过去不愿添加长路径的原因有很多,以及为什么我们仍然对此保持谨慎<…>。 <…> \\?\前缀不仅允许长路径;它会导致通过Windows API进行最少的修改即可将路径传递到文件系统。结果是\\?\关闭了Windows API执行的文件名规范化,包括删除尾随空格,扩展“。”。和’..’,将相对路径转换为完整路径,依此类推。<…> <…>带有\\?\前缀的长路径可以在大多数与 文件相关的 Windows API中使用,但不能在所有Windows API中使用。例如,如果文件名长于MAX_PATH,则LoadLibrary <…>失败。<…>整个Windows API中都有类似的示例。存在一些变通办法,但它们是逐案的。 <…>的另一个因素是与其他基于Windows的应用程序以及Windows Shell本身的兼容性。 由于此问题变得越来越普遍,因此Microsoft一直在努力解决它。实际上,作为及时的Vista插件,您会注意到一些更改,这些更改减少了达到MAX_PATH限制的机会:许多特殊文件夹的名称已缩短,更有趣的是,shell使用了自动路径收缩功能。 <…>尝试将其压缩为260个字符。
我们过去不愿添加长路径的原因有很多,以及为什么我们仍然对此保持谨慎<…>。
<…> \\?\前缀不仅允许长路径;它会导致通过Windows API进行最少的修改即可将路径传递到文件系统。结果是\\?\关闭了Windows API执行的文件名规范化,包括删除尾随空格,扩展“。”。和’..’,将相对路径转换为完整路径,依此类推。<…>
<…>带有\\?\前缀的长路径可以在大多数与 文件相关的 Windows API中使用,但不能在所有Windows API中使用。例如,如果文件名长于MAX_PATH,则LoadLibrary <…>失败。<…>整个Windows API中都有类似的示例。存在一些变通办法,但它们是逐案的。
<…>的另一个因素是与其他基于Windows的应用程序以及Windows Shell本身的兼容性。
由于此问题变得越来越普遍,因此Microsoft一直在努力解决它。实际上,作为及时的Vista插件,您会注意到一些更改,这些更改减少了达到MAX_PATH限制的机会:许多特殊文件夹的名称已缩短,更有趣的是,shell使用了自动路径收缩功能。 <…>尝试将其压缩为260个字符。
警告:您可能需要直接调用Windows API,因为我认为.NET Framework可能不支持这种路径语法。