最好检查长度是否超过MAX_PATH或捕获PathTooLongException?

时间:2014-05-11 04:38:04

标签: c# validation filesystems try-catch

我正在编写一个使用System.IO方法处理文件和目录的C#程序。其中一些方法包括Directory.GetDirectoriesDirectory.GetFilesPath.GetDirectoryName,如果路径太长,这些方法都会抛出PathTooLongException异常。我的第一个问题是Microsoft .NET Framework是否强制执行路径的最大长度,就像在C ++中调用Windows API一样? C#中超出string的路径(在MAX_PATH中)是否会导致PathTooLongException被抛出?

我应该使用它吗?

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;
}

3 个答案:

答案 0 :(得分:4)

判断力更好。

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

很难想象你会得到大量路径太长错误的情况,除非你试图做一些复制或将树移动到已经很深的目录节点的事情。在这种情况下,你可能最好先测试一下,这样你就不会创建一个在中间失败的大型慢速操作。

然而,硬编码的260无论如何都是一个坏主意,因为previous answer显示。

没有内置的Windows功能可以为给定的系统提供真正的答案,但您可以在开始操作之前通过试验和错误(可能是二进制搜索)在用户系统上确定答案。

但是,如果您阅读我引用的文章,您将看到您可以轻松地在程序中创建更长的路径,而不是在Windows中运行良好。一旦你达到255个字符,Windows资源管理器就会出现问题,所以如果您对此事有任何选择,我建议最多限制255个。

答案 1 :(得分:3)

将代码硬编码到代码中通常不是最好的主意。作为FYI,目录名称必须而不是248个字符,并且最大文件名长度必须 <{1}}个字符。如果您正在寻找太长的路径,那么您现有的代码已经存在漏洞。

question解决了该问题并提供了一些解决方案。如果要对路径使用固定长度,可以执行类似

的操作
260

您还可以使用反射来查找最大路径长度。我会使用反射来获取最大路径长度ONCE,然后存储该变量并在后续调用中使用它。

public static bool IsPathWithinLimits (string fullPathAndFilename)
{
     const int MAX_PATH_LENGTH = 259;//260-1
     return fullPathAndFilename.Length<=MAX_PATH_LENGTH;
}

注意:此代码尚未经过测试。

答案 2 :(得分:1)

我认为您不确定MAX_PATH如何在引擎盖下使用的事实表明,抓住异常而不是尝试自己执行检查会更好。

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

当然,这条规则有例外。例如,如果我有一个方法接受了一堆参数,然后将这些参数传递给其他各种方法,我可能想要预先执行一些检查,这样我就不会因为只有一半而处于某种奇怪状态参数有效。

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