小编典典

如何处理名称长度超过259个字符的文件?

c#

我正在开发一个应用程序,该应用程序遍历某些目录中的每个文件,并对这些文件执行一些操作。除其他外,我必须检索文件大小和修改此文件的日期。

某些文件全名(目录+文件名)太长,我无法使用.NET Framework
FileInfo,它被限制为MAX_PATH(260个字符)。许多Web来源建议通过P / Invoke使用本机Win32函数来访问名称过长的文件。

当前,Win32函数似乎会出现完全相同的问题。例如对于GetFileAttributesEx(270字节)的路径(kernel32.dll)失败,并出现Win32错误3
ERROR_PATH_NOT_FOUND。

可以从Notepad2成功打开相同的文件,并使用Windows资源管理器成功显示该文件(例如,由于259个字符的限制¹,Visual Studio
2010无法打开它)。

文件路径为270个字符长时,我该怎么办才能访问文件?

笔记:

  • 删除或忽略文件路径长度超过259个字符的文件不是解决方案。

  • 我仅在寻找与Unicode兼容的解决方案。

  • 该应用程序将在Windows 2008 / Vista或更高版本(安装了.NET Framework 4)下运行。


¹令人惊讶的是,Microsoft Word 2007失败,抱怨没有软盘驱动器的计算机上的“软盘太小”,或者当剩余4 GB的RAM时抱怨“
RAM内存不足”,或者最后是“需要更新防病毒软件”。他们是否会停止一天至少在诸如Microsoft
Office之类的关键产品中显示如此愚蠢的毫无意义的错误?


阅读 2392

收藏
2020-05-19

共1个答案

小编典典

.NET 4.6.2解决方案

使用此处 \\?\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

阅读此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,因为我认为.NET Framework可能不支持这种路径语法。

2020-05-19