为什么Path.GetDirectoryName函数必须依赖于260个字符限制

时间:2014-04-01 08:52:24

标签: c# .net

public static void Main()
{
    // testing file name
    var fileName =
        "\\\\server7\\EmailAttachments\\myfolder\\abc\\2012\\1126\\e85c6b82-edc5-4ce1-9ad0-8025b92d0105-o.dom=38c55279fe168c290fb2b06a312b5d88&b=6f54a59ce903eeaff197f82937de4012.dom=38c55279fe168c290fb2b06a312b5d88&b=6f54a59ce903eeaff197f82937de4012=6f54a59ce903eeaff197f82937de4012.dom=38c55279fe168c290fb2b06a312b5d88&b=6f54a59ce903eeaff197f82937de4012";

    var directory = fileName.GetDirectory();
}

   public static string GetDirectory(this string fullyQualifiedFileName)
     {
         return Path.GetDirectoryName(fullyQualifiedFileName); // throwing exception here
     }

获得以下异常

  

发生System.IO.PathTooLongException HResult = -2147024690
  消息=指定的路径,文件名或两者都太长。完全   限定文件名必须少于260个字符,并且   目录名称必须少于248个字符。来源= mscorlib程序
  堆栈跟踪:          在System.IO.Path.NormalizePath(String path,Boolean fullCheck,Int32 maxPathLength,Boolean expandShortPaths)          在System.IO.Path.GetDirectoryName(字符串路径)          在f:\ Practice中的Sameer.FilePathExtension.GetDirectory(String fullyQualifiedFileName)   Projects \ Sameer \ Sameer \ FilePathExtension.cs:第137行InnerException:

我想知道为什么 GetDirectoryName 必须依赖路径或文件名字符限制。

4 个答案:

答案 0 :(得分:5)

如msdn网站所述

  

“完整路径不得超过260个字符以保持兼容性   使用Windows操作系统“

http://msdn.microsoft.com/en-us/library/system.io.pathtoolongexception(v=vs.100).aspx

以及它背后的原因你可以在这里找到,如下面的链接所示。

  

另一个问题是暴露会导致不一致的行为   长路径支持。可以在大多数情况下使用带有\?\前缀的长路径   与文件相关的Windows API,但不是所有Windows API。对于   例如,LoadLibrary,它将模块映射到的地址   如果文件名长于MAX_PATH,则调用进程失败。所以   这意味着MoveFile将允许您将DLL移动到这样的位置   它的路径超过260个字符,但是当你尝试加载时   DLL,它会失败。整个Windows都有类似的例子   蜜蜂;存在一些变通方法,但它们是逐案处理的。

     

另一个被认为更像疼痛因素的因素是   与其他基于Windows的应用程序和Windows的兼容性   shell本身,只能使用比MAX_PATH短的路径(注意   Vista shell试图软化这个限制,简要描述   下面)。这意味着如果.NET支持长路径,那么我们就会让你   创建无法通过资源管理器或命令访问的文件   提示。

     

也就是说,我们意识到强制实施260个字符的限制不是一个   合理的长期解决方案。我们的客户不会遇到这种情况   问题经常发生,但是当他们这样做时,他们是非常的   不便。可能的解决方法是P /调用Windows   API并使用\?\前缀,但这将是一个庞大的代码量   复制System.IO中的功能。所以要解决这个问题   问题,客户经常求助于大修目录   组织,人为地缩短目录名称(和更新   每个参考位置。)

http://blogs.msdn.com/b/bclteam/archive/2007/02/13/long-paths-in-net-part-1-of-3-kim-hamilton.aspx

答案 1 :(得分:1)

来自MSDN documentation

  

最大路径长度限制

     

在Windows API中(以下讨论了一些例外情况)   段落),路径的最大长度是MAX_PATH,即   定义为260个字符。本地路径的结构如下   顺序:驱动器号,冒号,反斜杠,名称组件分隔   反斜杠和终止空字符。例如,   驱动器D上的最大路径是" D:\某些256个字符的路径字符串"   在哪里""表示不可见的终止空字符   当前的系统代码页。 (字符<>用于此处   视觉清晰度,不能成为有效路径字符串的一部分。)

答案 2 :(得分:1)

在撰写本文时,有3种解决方法来解决Path.GetDirectoryName的问题,当提出原始问题时,该方法不存在

1-对于Windows 10版本1607及更高版本

要在Windows 10 / Windows Server 2016中启用对长路径的内置支持,请使用Regedit.exe编辑器在注册表项HKLM \ SYSTEM \ CurrentControlSet \ ControlFileSystem中将REG_DWORD的LongPathsEnabled参数设置为值1 < / p>

参考https://theitbros.com/destination-path-too-long-error-when-movingcopying-a-file/

2-将您的.NET Framework Target版本更改为 4.6.2或更高版本。 该版本支持长路径

参考https://docs.microsoft.com/en-us/dotnet/api/system.io.pathtoolongexception?redirectedfrom=MSDN&view=netframework-4.6.2

3-对于目标框架版本为 4.6.1或更早版本的.NET应用,请将其添加到app.config

<?xml version=”1.0″ encoding=”utf-8″?>
<configuration>
<startup>
<supportedRuntime version=”v4.0″ sku=”.NETFramework,Version=v4.0″/>
</startup>
<runtime>
<AppContextSwitchOverrides value=”Switch.System.IO.UseLegacyPathHandling=false;Switch.System.IO.BlockLongPaths=false” />
</runtime>
</configuration>

这避免了OP要求的Path.GetDirectoryName异常,但是您仍然无法创建长目录。

参考https://theitbros.com/destination-path-too-long-error-when-movingcopying-a-file/ 解决方案7

答案 3 :(得分:0)

它只是应用于输入的验证,因此输出是有效路径。在返回路径将用于进一步调用文件系统(通常是这种情况)的情况下,这是可取的。从技术上讲,您不需要添加此验证,但如果它有益于您最常见的情况,那么它是一个很好的设计。除此之外,我怀疑此方法使用通用内部代码进行路径解析,而不是仅为此方法复制解析代码。