最好检查长度是否超过MAX_PATH或捕获PathTooLongException
本文关键字:PATH PathTooLongException MAX 检查 是否 | 更新日期: 2023-09-27 18:02:47
我正在编写一个使用System.IO
方法处理文件和目录的c#程序。其中一些方法包括Directory.GetDirectories
、Directory.GetFiles
和Path.GetDirectoryName
,如果路径太长,它们都可能抛出PathTooLongException
异常。我的第一个问题是,微软。net框架是否强制执行路径的最大长度,就像在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;
}
孰优孰劣
捕获异常比测试条件和完全避免异常要慢得多。但是,除非您将要遇到大量异常,否则性能差异并不重要。
很难想象你会得到大量的路径过长错误,除非你试图做一些事情,复制或移动树到一个已经很深的目录节点。在这种情况下,您最好预先测试所有内容,这样您就不会创建一个会在中间失败的大型缓慢操作。
然而,正如前面的答案所示,硬编码的260无论如何都是一个坏主意。
没有内置的windows函数可以给出给定系统的真实答案,但是在开始操作之前,您可以简单地在用户系统上通过试错(可能是二进制搜索)来确定答案。
然而,如果您阅读了我所引用的文章,您将会看到,您可以轻松地在程序中创建比在windows中更长的路径。Windows资源管理器一旦达到255个字符就会出现问题,所以长话短说,如果您有选择的话,我建议最多限制为255个字符。
将值硬编码到代码中通常不是最好的主意。仅供参考,目录名必须小于 248
字符,最大文件名长度小于 260
字符。如果你正在寻找太长的路径,你现有的代码已经有一个漏洞。
这个问题解决了这个问题并提供了一些解决方案。如果您希望使用固定长度的路径,您可以这样做
public static bool IsPathWithinLimits (string fullPathAndFilename)
{
const int MAX_PATH_LENGTH = 259;//260-1
return fullPathAndFilename.Length<=MAX_PATH_LENGTH;
}
您也可以使用反射来查找最大路径长度。我会使用反射来获得一次最大路径长度,然后存储该变量并在随后的调用中使用它。
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;
}
}
我认为您不确定MAX_PATH
在底层是如何使用的这一事实表明,最好是捕获异常,而不是试图自己执行检查。
我的一般哲学是,实际使用数据块的代码应该负责检查它的有效性。因为你的getFolderName
方法不与path
做任何事情,而不是将其传递给GetDirectoryName
,我不会费心检查长度,甚至可能不会费心检查它是否为空/null。把它传下去,让GetDirectoryName
去操心吧。
作为旁注,我相信c#(可能是所有。net)会自动将所有变量初始化为默认值,因此将folderName
初始化为String.Empty
是多余的。