为什么Directory :: EnumerateFiles和DirectoryInfo :: EnumerateFiles抛出不同的异常?

时间:2013-07-19 12:38:23

标签: c# .net exception-handling

成员函数DirectoryInfo::EnumerateFiles只能投放DirectoryNotFoundExceptionSecurityException

而静态函数Directory::EnumerateFiles可以抛出相同的异常以及许多其他异常,例如PathTooLongExceptionUnauthorizedAccessExceptionIOException

为什么?

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

3 个答案:

答案 0 :(得分:2)

原因在于它们的使用方式。 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 = new DirectoryInfo(@"C:\myfolder");

如果它无效,例如。因为路径太长,你会在这里得到一个例外。

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

  • 嘿,我加载的目录 - 为我枚举上面的文件。

myObject.EnumerateFiles();

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

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

因此它将加载文件夹(可以生成所有这些异常),然后枚举文件,只需一步。

有关PathTooLongException的一些信息:

包含完整路径的文件的最大长度为260个字符。因此,如果您有一个长度为250个字符的文件夹,如c:\ aaaaaaaaaaaaaaaa ...,您可能会认为将20个字符长的文件放入该文件夹(总共270个)会导致DirectoryInfo抛出例外。

然而,根本无法将文件放在文件夹中 - 窗口会出错:

  

目标文件夹的文件名太长了。

所以DirectoryInfo.EnumerateFiles不可能被欺骗超过260的最大长度,因为不可能创建超过260个字符的任何东西。

答案 1 :(得分:1)

静态Directory方法需要一个参数指向目录,而DirectoryInfo方法是已创建的DirectoryInfo对象的实例方法。因此,当Directory方法调用它的方法时,DirectoryInfo方法可能会引入{{1}}方法不再存在的问题,例如:

  • ArgumentException
  • ArgumentNullException
  • DirectoryNotFoundException
  • PathTooLongException

但是,如果您查看constructor of DirectoryInfo,您会发现这些可能存在的问题已在此处理。

答案 2 :(得分:0)

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

  

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

你如何处理它们取决于你,但除非异常意味着你特意你将会因此而采取不同的行动,那么就这样做:

try
{
    ...
}
catch (Exception ex)
{
    ...
}

这将抓住所有人。

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

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