C# 为什么Directory::EnumerateFiles和DirectoryInfo::EnumerateFiles会引发不同的异常?

C# 为什么Directory::EnumerateFiles和DirectoryInfo::EnumerateFiles会引发不同的异常?,c#,.net,exception-handling,C#,.net,Exception Handling,成员函数只能抛出DirectoryNotFoundException和SecurityException 而静态函数可以抛出相同的异常以及许多其他异常,如PathTooLongException,UnauthorizedAccessException,IOException 为什么? 我需要编写健壮的代码。 当在C#目录中的文件上迭代时,处理异常的最佳方法是什么?它可以抛出更多异常,因为它在一次调用中处理用于执行异常的对象的构造和销毁 在C#目录中的文件上迭代时,处理异常的最佳方法是什么 你如何

成员函数只能抛出
DirectoryNotFoundException
SecurityException

而静态函数可以抛出相同的异常以及许多其他异常,如
PathTooLongException
UnauthorizedAccessException
IOException

为什么?

我需要编写健壮的代码。
当在C#目录中的文件上迭代时,处理异常的最佳方法是什么?

它可以抛出更多异常,因为它在一次调用中处理用于执行异常的对象的构造和销毁

在C#目录中的文件上迭代时,处理异常的最佳方法是什么

你如何处理它们取决于你,但除非例外情况对你有特别的意义,你会因为它而做一些不同的事情,那么就这样做:

try
{
    ...
}
catch (Exception ex)
{
    ...
}
这会抓住他们所有人

如果您想处理其中的每一个,它将如下所示:

try
{
}
catch (DirectoryNotFoundException ex)
{
}
catch (SecurityException ex)
{
}
etc...

原因在于它们的使用方式
DirectoryInfo::EnumerateFiles
在当前目录下工作,因此从本质上讲,将目录加载到对象中的工作已经完成了—担心路径过长等问题是通过构建
DirectoryInfo
对象来完成的,例如:

DirectoryInfo di = new DirectoryInfo(...); // Gets the directory - many things could go wrong here

di.EnumerateFiles(); // Since we have a DirectoryInfo object, we already know the directory is ok - we've checked for the other problems already.
Directory.EnumerateFiles
是一个静态方法,这意味着它不能在已成功创建的现有对象上工作。因此,它必须加载目录(这可能导致任何数量的异常),然后枚举文件

它本质上是将最上面的两个步骤合并为一个步骤

用英语来看,另一种方式是:

  • 将此目录加载到对象c:\myfolder中
DirectoryInfo myObject=newdirectoryinfo(@“C:\myfolder”)

如果它无效,例如,因为路径太长,您将在这里得到一个异常

如果有效,它现在将目录的相关信息加载到对象中。所以你可以说

  • 嘿,我加载的目录-为我枚举其中的文件
myObject.EnumerateFiles()

因为它已经加载了文件夹,所以不需要再次加载,因为它知道它工作正常并且完全正常。唯一的可能性是找不到(如果在这两行之间,您删除了计算机上的文件夹)和SecurityException,即您没有枚举权限

另一个示例结合了这两个步骤,并说“为我枚举此文件夹中的所有文件”

因此,它将加载文件夹(可能会生成所有这些异常),然后枚举文件,所有这些都在一个步骤中完成

有关PathTooLongException的一些信息:

包含完整路径的文件的最大长度为260个字符。因此,如果您有一个类似c:\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa。。。。。这是250个字符长,您可能认为将一个20个字符长的文件放入文件夹(总共270个字符)会导致DirectoryInfo引发异常

但是,无法将文件放在文件夹中-windows会给出错误:

文件名对于目标文件夹来说太长


因此,DirectoryInfo.Enumerate文件不可能被欺骗超过最大长度260,因为不可能创建超过260个字符的文件。

静态
目录
方法需要一个参数作为目录路径,而
DirectoryInfo
方法是实例方法在已创建的
DirectoryInfo
对象上。因此,
Directory
方法可能会引入
DirectoryInfo
方法在调用其方法时不再存在的问题,例如:

  • 论据例外
  • 无参数异常
  • DirectoryNotFoundException
  • PathTooLongException

但是,如果您查看一下,您会发现这些可能的问题已经在那里得到了处理。

另请参见,您的意思是“di.EnumerateFiles()”没有理由抛出PathTooLongException,即使di包含深度嵌套的目录?我觉得这很奇怪。我无法想象DirectoryInfo的构造函数会执行所有这些检查,即使是对于嵌套的DirectoriesRect,因为如果路径太长,您将无法执行新DirectoryInfo(…)的第一行
和.Enumerate文件必须在您创建的对象上执行。当在深度嵌套目录中的枚举中发现PathTooLong时,PathTooLong会发生什么情况?我不认为所有可能的检查都是由顶级DirectoryInfo构造函数递归完成的??一个有趣的问题,我试过了,答案是,你不能在你的计算机上创建一个超过260个字符(包括文件名)的文件。因此,该方法永远不会出现抛出错误的情况。我更新了我的答案来解释更多。这不是真的,当然文件路径可以超过260个字符(NTFS的基本功能)。只有像Explorer这样的一些工具不支持这一点。是的,那不是开玩笑。Windows 10资源管理器也支持更长的文件路径。关于.NET:在.NET 4.6.2之前,不直接支持更长的路径(但间接支持)。但是这里有一条.NET 4.6.2新闻:现在支持它们:我需要不同地处理这些异常如果给定的DirectoryInfo表示具有有效路径(即不太长)的目录,但包含一个嵌套太深的子目录,会发生什么情况?我无法想象PathTooLong的检查是针对所有包含的子目录递归完成的?