C# 最好检查长度是否超过MAX_PATH或catch PathTooLongException?

C# 最好检查长度是否超过MAX_PATH或catch PathTooLongException?,c#,validation,filesystems,try-catch,C#,Validation,Filesystems,Try Catch,我正在编写一个C程序,它使用System.IO方法处理文件和目录。其中一些方法包括Directory.GetDirectories、Directory.GetFiles和Path.GetDirectoryName,如果路径太长,这些方法都会引发PathTooLongException异常。我的第一个问题是,微软.NETFramework是否执行路径的最大长度,就像调用C++中的Windows API一样?C#中的路径(在字符串中)超过MAX_path是否会导致抛出PathToolLongExce

我正在编写一个C程序,它使用
System.IO
方法处理文件和目录。其中一些方法包括
Directory.GetDirectories
Directory.GetFiles
Path.GetDirectoryName
,如果路径太长,这些方法都会引发
PathTooLongException
异常。我的第一个问题是,微软.NETFramework是否执行路径的最大长度,就像调用C++中的Windows API一样?C#中的路径(在
字符串中)超过
MAX_path
是否会导致抛出
PathToolLongException

我应该用这个吗

string getFolderName(string path) 
{
    if (string.IsNullOrWhiteSpace(path))
        return string.Empty;

    if (path.Length > 260)
    {
        System.Diagnostics.Debug.WriteLine("Path is too long.");
        return string.Empty;
    }

    string folderName = System.IO.Path.GetDirectoryName(path);

    return folderName;
}
还是这个

string getFolderName(string path) 
{
    if (string.IsNullOrWhiteSpace(path))
        return string.Empty;

    string folderName = string.Empty;

    try {
        folderName = System.IO.Path.GetDirectoryName(path);
    }
    catch (System.IO.PathTooLongException)
    {
        System.Diagnostics.Debug.WriteLine("Path is too long.");
    }

    return folderName;
}

更好的办法是作出判断

捕获异常比测试条件和完全避免异常要慢得多。但是,除非您将遇到大量异常,否则性能差异根本不重要

很难想象会出现大量路径过长错误的情况,除非您正在尝试将树复制或移动到已经很深的目录节点中。在这种情况下,你最好在前面测试所有的东西,这样就不会在中间产生一个大的慢操作。

然而,硬编码的260无论如何都是个坏主意,如图所示

没有内置的windows函数可以为给定的系统提供真正的答案,但是在开始操作之前,您可以简单地通过用户系统上的反复试验(可能是二进制搜索)来确定答案


但是,如果您阅读了我引用的文章,您将看到,您可以轻松地在程序中创建比在windows中工作更好的更长路径。Windows资源管理器在达到255个字符时出现问题,长话短说,如果您在这件事上有任何选择,我建议最多限制255个。

我认为您不确定如何在引擎盖下使用
MAX\u PATH
,这表明最好捕获异常,而不是自己尝试执行检查

我的基本理念是,实际使用一段数据的代码应该负责检查它是否有效。由于您的
getFolderName
方法除了将其传递给
GetDirectoryName
之外,对
path
不做任何操作,因此我不会检查长度,甚至可能不会检查它是否为空/空。把它传过去,让
GetDirectoryName
去担心它

当然,这条规则也有例外。例如,如果我有一个方法,它接受了一组参数,然后将这些参数传递给其他各种方法,那么我可能需要提前执行一些检查,这样我就不会因为只有一半的参数是有效的而陷入某种奇怪的状态


作为补充说明,我相信C#(可能是所有.NET)会自动将所有变量初始化为其默认值,因此将
folderName
初始化为
String.Empty
是多余的。

将值硬编码为代码通常不是最好的主意。仅供参考,目录名必须少于
248
个字符,最大文件名长度必须少于
260个字符。如果专门查找太长的路径,则现有代码已经有漏洞

这解决了这个问题,并提供了一些解决方案。如果要为路径使用固定长度,可以执行以下操作

public static bool IsPathWithinLimits (string fullPathAndFilename)
{
     const int MAX_PATH_LENGTH = 259;//260-1
     return fullPathAndFilename.Length<=MAX_PATH_LENGTH;
}
公共静态bool IsPathWithinLimits(字符串fullPathAndFilename)
{
const int MAX_PATH_LENGTH=259;//260-1

return fullPathAndFilename.LengthWhere you get
MAX_PATH
from?捕获
PathTooLongException
几乎肯定会更可靠,因为它被烘焙到您调用的代码中。请注意,如果您不想处理异常,您甚至不需要try/catch;只要让它传播到被调用方即可R.“我相信C.*(也许所有.NET)自动将所有变量初始化为它们的默认值,所以初始化FoLDNEXT到String。空是多余的。”.<代码> String。空< /代码>不是<>代码> String < /C> >的默认值:<代码> NULL>代码>。请考虑编辑您的答案以删除误导性信息。
public class PathHelper
{
     private static int MaxPathLength {get; set;}

     static PathHelper()
     {
          // reflection
          FieldInfo maxPathField = typeof(Path).GetField("MaxPath", 
              BindingFlags.Static | 
              BindingFlags.GetField | 
              BindingFlags.NonPublic );

          // invoke the field gettor, which returns 260
          MaxPathLength = (int) maxPathField.GetValue(null);
         //the NUL terminator is part of MAX_PATH https://msdn.microsoft.com/en-us/library/aa365247.aspx#maxpath
               MaxPathLength--; //So decrease by 1

     }


     public static bool IsPathWithinLimits (string fullPathAndFilename)
     {          
          return fullPathAndFilename.Length<=MaxPathLength;
     }

}