【问题标题】:Catching IOException捕获 IOException
【发布时间】:2015-01-29 09:00:36
【问题描述】:

我正在编写一个 C# 应用程序,如果文件已被某个进程使用,并且如果该文件不存在,则应用程序需要显示另一条消息。

类似这样的:

try 
{
    //Code to open a file
}
catch (Exception e)
{
    if (e IS IOException)
    {
        //if File is being used by another process
        MessageBox.Show("Another user is already using this file.");

        //if File doesnot exist
        MessageBox.Show("Documents older than 90 days are not allowed.");
    }
}

既然IOException涵盖了这两种情况,那么如何区分是因为File被另一个进程使用还是File不存在而捕获了这个异常?

任何帮助将不胜感激。

【问题讨论】:

  • 你确定它只是在这两种情况下都抛出IOException吗?例如不是FileNotFoundException? (为什么要捕获Exception,然后使用is 而不是在单独的捕获块中捕获IOException?)
  • 你知道你可以像这样使用 catch:catch(IOException ioe){//handle ie exception}catch(Exception e){//handle unknown exception}
  • FileNotFoundException 会在文件不存在时抛出。更多信息在这里:dotnetperls.com/ioexception

标签: c# file-io io inputstream


【解决方案1】:

始终从最具体的异常类型到最通用的异常类型。 每个异常都继承Exception-class,因此您将在catch (Exception) 语句中捕获任何异常

这将分别过滤 IOExceptions 和其他所有异常:

catch (IOException ioEx)
{
     HandleIOException(ioEx);
}
catch (Exception ex)
{
     HandleGenericException(ex);
}

所以抓住Exception 总是最后。检查 if 是可能的,但不常见。

关于您的问题:

if (File.Exists(filePath)) // File still exists, so obviously blocked by another process

这将是分离条件的最简单解决方案。

【讨论】:

  • 检查 File.Exists() 可能更有意义。如果找不到文件在逻辑上是预期的情况,则检查它而不是“预期的 excpetion”。除非你真的有一些全局性的事情要做,比如在网站上显示错误页面或记录错误,否则不要捕捉“异常”,这是一个真正的坏习惯。考虑一下“OutOfMemoryException”,它总是在执行代码时发生,这个应该冒泡,让应用程序崩溃,也许在尝试记录之后,可能是一种处理它的明智方法。
  • @SharpShade 这正是我所做的。除了我没有检查文件是否存在这一事实。谢谢
【解决方案2】:

如你所见hereFile.OpenRead 可以抛出这些异常类型

  1. ArgumentException
  2. ArgumentNullException
  3. PathTooLongException
  4. DirectoryNotFoundException
  5. UnauthorizedAccessException
  6. FileNotFoundException
  7. NotSupportedException

对于每种异常类型,您都可以用这种方式处理它

try{

}
catch(ArgumentException e){
  MessageBox.Show("ArgumentException ");
}
catch(ArgumentNullExceptione e){
 MessageBox.Show("ArgumentNullExceptione");
}
.
.
.
.        
catch(Exceptione e){
     MessageBox.Show("Generic");
}

在您的情况下,您只能处理一种或两种类型,而其他类型始终被通用 Exception 捕获(它必须始终是最后一个,因为包含所有异常)

【讨论】:

  • 那么,一个方法中有 7 个异常处理程序?我认为不会。
  • 这是一种展示如何处理异常的通用方式。如果您只需要两个,则可以捕获这两种类型和通用异常
  • @Polyfun 对不同的异常类型采取行动并没有错,如果您想对每种异常采取不同的行动怎么办?
【解决方案3】:

尝试以下方法:

try
{
  //open file
}
catch (FileNotFoundException)
{
  MessageBox.Show("Documents older than 90 days are not allowed.");
}
catch (IOException)
{
  MessageBox.Show("Another user is already using this file.");
}

更多信息:http://www.dotnetperls.com/ioexception

【讨论】:

    【解决方案4】:

    我知道这是旧的,但唯一一致的解决方案是通过 HResult 属性过滤 catch 块。我不知道它是哪一个,但这是一个复制文件并捕获文件是否已存在的示例:

            try
            {
                File.Copy(source, dest, false);// Try to copy the file normally
            }
            catch (IOException e) when (e.HResult == -2147024816)// 0x80070050 : The file already exists
            {
                 /*Prompt user for overwrite...*/
            }
    

    查阅 .NET 参考源并跟踪 Win32 调用以查找返回的 HResult。

    【讨论】:

      【解决方案5】:

      当文件不存在时会抛出继承IOException的FileNotFoundException,所以可以这样写:

      try 
      {
          //file operate
      }
      catch (FileNotFoundException ex)
      {
          MessageBox.Show("Documents older than 90 days are not allowed.");
      }
      catch (IOException ex)
      {
          MessageBox.Show("Another user is already using this file.");
      }
      

      【讨论】:

        猜你喜欢
        • 2012-12-19
        • 2018-02-10
        • 2011-03-14
        • 2012-10-18
        • 2012-11-02
        • 2017-05-24
        • 2018-04-07
        • 2014-10-09
        • 1970-01-01
        相关资源
        最近更新 更多