代码之家  ›  专栏  ›  技术社区  ›  Cubicle

请确认.NET 4.0中与路径长度相关的行为的更改

  •  4
  • Cubicle  · 技术社区  · 16 年前

    有人能确认微软在.NET 4.0中更改了与路径长度相关的某些类的行为吗?例如,下面的代码在.NET 3.5上运行良好,但在4.0上却为我抛出了一个pathtoolongexception。

    const string prefix = "C:\\";
    const string suffix = ".txt";
    
    var sb = new StringBuilder();
    sb.Append(prefix);
    for (var i = 0; i < 260 - prefix.Length - suffix.Length - 1; i++)
    {
        sb.Append("a");
    }
    sb.Append(suffix);
    
    var info = new FileInfo(sb.ToString());
    

    此外,还呼吁 File.Create(sb.ToString()) 在.NET 3.5上引发IOException,但在.NET 4.0上引发PathToolOngException。可能会有更多的差异。

    这些变更是否记录在某个地方?

    谢谢您!

    [编辑]

    我听从了HansPassant的建议,在connect.microsoft.com上提交了一份报告。你可以找到它 here .

    2 回复  |  直到 16 年前
        1
  •  5
  •   Hans Passant    16 年前

    编辑我的答案时,原来的答案是错误的。是的,path.normalizePath()方法在.NET 4.0中进行了一些主要更改。我设法用引用源对其进行了调试,并在源代码中找到了解释其行为的注释:

        // The max total path is 260, and the max individual component length is 255. 
        // For example, D:\<256 char file name> isn't legal, even though it's under 260 chars. 
        internal static readonly int MaxPath = 260;
        private static readonly int MaxDirectoryLength = 255; 
        ...
            if (newBuffer.Length - 1 - lastDirectorySeparatorPos > MaxDirectoryLength)
            { 
                throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong")); 
            }
    

    这是被代码绊倒的例外。这看起来很奇怪,因为代码似乎检查了目录名的长度,显然您的代码中的长度不接近255个字符。但是,注释解释了为什么拒绝您的路径,路径的文件名部分是259-3=256个字符。太多了。

    我以前没有意识到这一限制,我有点怀疑 全部的 Windows版本有此限制。我所看到的所有文档都记录了目录名的最大长度(路径减去文件名)。代码中还有其他注释表明Windows2000中存在一个一次性错误,这可能与此有关。

    不管怎样,你可以通过改变自己来看到这个

            const string prefix = "C:\\a\\";
    

    现在接受了259个字符的路径字符串。换句话说,只有当路径名引用驱动器根文件夹时,此行为才应该是字节。不是你应该存放文件的地方。

    考虑到源代码中的注释,这种更改是有意的,应该将其视为一个特性,而不是一个bug。不过,我在您开始的反馈文章中发表了一条评论。我还没有完全买下它…


    最新消息:好吧,我被卖了。我尝试在Wi7上用C++创建这样一个文件,但失败了。根目录中的文件的路径名不能超过258个字符。限制似乎是由 成分 路径(子目录名、文件名)的长度不允许超过255个字符。.NET 4.0行为完全正确。

        2
  •  0
  •   John Weldon user3678248    16 年前

    你检查过 File.Create() 方法中的反射镜,并比较了两种版本?