最好检查长度是不是超过 MAX_PATH 或捕获 PathTooLongException?
Posted
技术标签:
【中文标题】最好检查长度是不是超过 MAX_PATH 或捕获 PathTooLongException?【英文标题】:Better to check if length exceeds MAX_PATH or catch PathTooLongException?最好检查长度是否超过 MAX_PATH 或捕获 PathTooLongException? 【发布时间】:2014-06-28 15:07:02 【问题描述】:我正在编写一个使用System.IO
方法处理文件和目录的C# 程序。其中一些方法包括Directory.GetDirectories
、Directory.GetFiles
和Path.GetDirectoryName
,如果路径太长,它们都会抛出PathTooLongException
异常。我的第一个问题是 Microsoft .NET Framework 是否强制执行路径的最大长度,与在 C++ 中调用 Windows API 的方式相同吗? C# 中超过MAX_PATH
的路径(在string
中)是否会导致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;
【问题讨论】:
你从哪里得到MAX_PATH
?捕获PathTooLongException
几乎肯定会更可靠,因为它已包含在您调用的代码中。请注意,如果您不想处理异常,您甚至不需要 try/catch;让它传播给调用者。
【参考方案1】:
将值硬编码到代码中通常不是最好的主意。仅供参考,目录名称必须小于 小于248
字符,最大文件名长度必须小于 小于260
字符。如果您专门寻找过长的路径,那么您现有的代码已经存在漏洞。
question 解决了这个问题并提供了一些解决方案。如果你想为路径使用固定长度,你可以这样做
public static bool IsPathWithinLimits (string fullPathAndFilename)
const int MAX_PATH_LENGTH = 259;//260-1
return fullPathAndFilename.Length<=MAX_PATH_LENGTH;
您还可以使用反射来找到最大路径长度。我会使用反射来获得最大路径长度 ONCE,然后存储该变量并在后续调用中使用它。
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;
注意:此代码未经测试。
【讨论】:
【参考方案2】:我认为,您不确定 MAX_PATH
是如何在后台使用的这一事实表明,最好捕获异常而不是尝试自己执行检查。
我的一般理念是,实际使用数据的代码应该负责检查它是否有效。由于您的getFolderName
方法除了将其传递给GetDirectoryName
之外对path
没有任何作用,我不会费心检查长度,甚至可能不会费心检查它是否为空/空。把它传递给GetDirectoryName
就可以了。
当然,这条规则也有例外。例如,如果我有一个方法接收一堆参数,然后将这些参数传递给其他各种方法,我可能想预先进行一些检查,这样我就不会陷入某种奇怪的状态,因为只有一半参数有效。
附带说明,我相信 C#(可能是所有 .NET)会自动将所有变量初始化为其默认值,因此将 folderName
初始化为 String.Empty
是多余的。
【讨论】:
“我相信 C#(可能是所有 .NET)会自动将所有变量初始化为其默认值,因此将 folderName 初始化为 String.Empty 是多余的。”。String.Empty
不是 string
的默认值:null
是。请考虑编辑您的答案以删除误导性信息。【参考方案3】:
更好的是判断电话。
捕获异常比测试条件和完全避免异常要慢得多。但是,除非您将遇到大量异常,否则性能差异根本不重要。
很难想象会出现大量路径太长错误的情况,除非您尝试将树复制或移动到已经很深的目录节点中。在这种情况下,您最好预先测试所有内容,这样您就不会创建一个会在中间失败的大型缓慢操作。
但是,正如previous answer 所示,硬编码 260 无论如何都是个坏主意。
没有内置的 windows 功能可以为给定系统提供真正的答案,但您可以在开始操作之前通过用户系统上的反复试验(可能是二进制搜索)来简单地确定答案。
但是,如果您阅读了我引用的文章,您会发现在程序中创建比在 Windows 中运行良好的路径更容易。一旦达到 255 个字符,Windows 资源管理器就会出现问题,长话短说,如果您有任何选择,我建议最多限制为 255 个。
【讨论】:
以上是关于最好检查长度是不是超过 MAX_PATH 或捕获 PathTooLongException?的主要内容,如果未能解决你的问题,请参考以下文章
最好“尝试”一些东西并捕获异常或测试是不是可以首先避免异常?
通过`getDisplayMedia`检查浏览器/平台是不是支持屏幕捕获