c# - 如何处理名称超过 259 个字符的文件?

标签 c# windows file-io interop pinvoke

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

有些文件全名(目录+文件名)太长,无法使用.NET Framework FileInfo,限制在MAX_PATH(260个字符) .许多网络资源建议通过 P/Invoke 使用 native Win32 函数来访问名称过长的文件。

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

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

当文件路径长度为 270 个字符时,如何才能访问文件?

注意事项:

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

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

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


¹ 令人惊讶的是,Microsoft Word 2007 失败,在没有任何软盘驱动器的计算机上提示“软盘太小”,或者当有 4 GB 的内存时“RAM 内存不足” RAM 剩余,或最终显示“防病毒软件 [...] 需要更新”。至少有一天,他们会停止在 Microsoft Office 等关键产品中显示这种愚蠢且毫无意义的错误吗?

最佳答案

.NET 4.6.2 解决方案

使用 \\?\C:\Verrrrrrrrrrrry 长路径 语法,如所述 here .

.NET 核心解决方案

之所以有效,是因为框架为您添加了长路径语法。

.NET 4.6.2 之前的解决方案

还使用长路径语法和 Unicode 版本的 Win32 API 函数与 P/Invoke。 来自 Naming Files, Paths, and Namespaces :

The Windows API has many functions that also have Unicode versions to permit an extended-length path for a maximum total path length of 32,767 characters. This type of path is composed of components separated by backslashes, each up to the value returned in the lpMaximumComponentLength parameter of the GetVolumeInformation function (this value is commonly 255 characters). To specify an extended-length path, use the \\?\ prefix. For example, \\?\D:\very long path.

阅读 this Microsoft Support page可能也很有趣。

Long Paths in .NET by Kim Hamilton at the BCL Team blog 中的非常详尽的解释列出了处理这些路径的一些障碍,他声称这是 .NET 仍然不直接支持此语法的原因:

There are several reasons we were reluctant to add long paths in the past, and why we’re still careful about it <...>.

<...> the \\?\ prefix not only enables long paths; it causes the path to be passed to the file system with minimal modification by the Windows APIs. A consequence is that \\?\ turns off file name normalization performed by Windows APIs, including removing trailing spaces, expanding ‘.’ and ‘..’, converting relative paths into full paths, and so on.<...>

<...> Long paths with the \\?\ prefix can be used in most of the file-related Windows APIs, but not all Windows APIs. For example, LoadLibrary<...> fails if the file name is longer than MAX_PATH. <...> There are similar examples throughout the Windows APIs; some workarounds exist, but they are on a case-by-case basis.

Another factor <...> is compatibility with other Windows-based applications and the Windows shell itself <...>

Because this problem is becoming increasingly common <...> there are efforts throughout Microsoft to address it. In fact, as a timely Vista plug, you’ll notice a couple of changes that reduce the chance of hitting the MAX_PATH limit: many of the special folder names have shortened and, more interestingly, the shell is using an auto-path shrinking feature <...> to attempt to squeeze them into 260 characters.


警告:您可能需要直接调用 Windows API,因为我认为 .NET Framework 可能不支持这种路径语法。

关于c# - 如何处理名称超过 259 个字符的文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5188527/

相关文章:

c# - 限制 MDI 应用程序中的窗口实例数

c# - ASP.net c# 试图在服务器上运行可执行文件

windows - 我可以在没有visual studio的情况下在windows 7中编译运行cuda程序吗?

python - 在文本文件中删除和插入行

c# - 这个图案的名字? (回答 : lazy initialization with double-checked locking)

c# - 带下划线的 MVC 3 模型绑定(bind)

C#:是否可以根据开关让单个应用程序充当控制台或 Windows 应用程序?

windows - 如何修复在 Windows 终端中启动 `powershell.exe' 时出现的错误 0x800700c1?

java - ObjectOutputStream 取 BufferedOutputStream 时不写入对象

perl - ./script 第 17 行没有这样的文件或目录