【问题标题】:How to know that File.Copy succeeded?如何知道 File.Copy 成功了?
【发布时间】:2011-12-17 18:53:54
【问题描述】:

静态方法File.Copy(String, String) 不返回值。我如何以编程方式知道该功能是否成功?如果没有抛出异常,File.Copy 运行良好。但我问的是如何将“无例外”作为条件。

类似这样的:

if(no exception happened){

//my code goes here

}

编辑:我已经使用一个简单的计数器解决了这个问题,如下所示:

int i=0;
try{
    File.Copy();
}
catch(e1){
    i++;
}
catch(e2){
    i++;
}

if(i==0){
    //my code goes here
}

感谢所有贡献者。我会仔细阅读您的答案以选择最佳答案。

【问题讨论】:

  • 我的猜测,如果它没有抛出异常(例如IOException)
  • 你可以用布尔值来做到这一点。
  • 在处理文件系统时,您必须学会忍受不确定性。如果有人在 File.Copy() 返回后立即绊倒电源线而没有引发异常,那么您仍然没有副本。不要为小事而烦恼,摆脱那些计数代码。

标签: c# .net exception return-value file-copying


【解决方案1】:

如果操作没有抛出任何异常,则说明它是成功的。可能的例外列表可在here 获得:

UnauthorizedAccessException

  • 调用者没有所需的权限。

ArgumentException

  • sourceFileNamedestFileName 是一个长度为零的字符串,仅包含空格,或者包含一个或多个由InvalidPathChars 定义的无效字符。

  • -或-

  • sourceFileNamedestFileName 指定一个目录。

ArgumentNullException

  • sourceFileName 或 destFileName 为空。

PathTooLongException

  • 指定的路径、文件名或两者都超过了系统定义的最大长度。例如,在基于 Windows 的平台上,路径必须少于 248 个字符,文件名必须少于 260 个字符。

DirectoryNotFoundException

  • 在 sourceFileName 或 destFileName 中指定的路径无效(例如,它位于未映射的驱动器上)。

FileNotFoundException

  • 找不到sourceFileName

IOException

  • destFileName 存在。

  • -或-

  • 发生了 I/O 错误。

NotSupportedException

  • sourceFileNamedestFileName 的格式无效。

【讨论】:

  • 虽然实际上没有必要,但您也可以使用File.Exists 仔细检查。
【解决方案2】:

虽然我不知道你处于什么情况,但我有类似的情况,我必须复制文件并且需要知道它是否成功,因为我在 .NET API 中找不到任何有用的东西,我唯一的选择是继续尝试直到成功(尝试次数)例如在下面的代码中我必须在 5 次尝试后放弃

private bool CopyDone()
{
  bool done = false;
  int i = 0;
  string source = "SourceFile";
  while (i < 5)
  {
    try
    {

      System.IO.File.Copy(source, target, true);
      i = 5;
      done = true;
    }
    catch (Exception exp)
    {
      Trace.WriteLine("File trouble " + exp.Message);
      System.Threading.Thread.Sleep(1000);
      i++;
    }

   }

  /* if(!done)
   {
      Trace.WriteLine("Failed to copy file "+source );
   }*/
  return done;

}

【讨论】:

  • 我认为这不是正确的方法,因此这不应该是公认的答案。操作是否完成。为什么你认为第n次的结果比第一次的结果好?
【解决方案3】:

错误

如果方法没有抛出异常,则没有发生错误。该方法能够执行它所承诺的工作,因此它会避开,并且不会尝试返回某种状态代码。您无需检查状态码,因为您会知道它已成功。

如果方法复制操作失败,将抛出异常。在这种情况下,该方法无法执行它所承诺的工作,这意味着发生了一些奇怪的(异常)事情,因此引发了异常。由于抛出了异常,你不得不处理它,或者你的程序崩溃了。所以检查状态码是没有意义的。无论如何,您无法编写任何能够读取该状态代码的代码,因为永远无法到达状态检查代码。代码流将转到catch 块,或程序终止。

这些概念是使用异常处理错误的基础。

如何处理异常

除非您需要,并且有一些合理的方法可以从异常中恢复,否则不要处理它们。让你的程序爆炸。这将使您更容易在野外发现代码中的错误,因为未处理的异常会产生堆栈跟踪,它会准确告诉您程序的哪个部分发生了故障,以及代码是如何到达那个点的。

如果您有合理的恢复方式(例如,简单地向用户显示错误消息并重试操作,或者让他们输入不同的参数),那么您可以编写一个try/catch 块。在try 块中编写可能引发异常的代码,在catch 块中编写恢复代码。

try
{
    var file = File.Open(filename);
    // Todo: Work with open file here
}
catch(FileNotFoundException e)
{
    MessageBox.Show("Failed to open file - " + e.ToString());
    // Todo: Additional recovery here,
    // like telling the calling code to re-open the file selection dialog
}

请注意,您永远不应该捕获基本的 Exception 类型,而应该捕获您可以处理的特定派生异常类型(例如 FileNotFoundException)。这是有道理的,因为您可能无法编写能够从OutOfMemoryException 成功恢复的代码,并且该异常可能会在您的代码中的任何位置抛出。如果您捕获了Exception,那么您正在编写尝试处理任何事情的代码,而不仅仅是您感兴趣的异常。

完成

File.Copy 是同步操作。所以一旦方法完成,那么实际的复制就完成了。

这意味着您可以在复制行之后立即编写一行代码。并且该代码可以期望该文件在那里,可以完全复制它,并且可以访问它。

【讨论】:

  • 谢谢,您的回答非常有用。 SSamra 的答案给出了直接的解决方案。
  • 我有问题。 File.Copy 不会引发异常,但它不会复制文件。想法?
【解决方案4】:

如果没有异常则说明文件完全复制成功...

using System;
using System.IO;

class Test 
{
    public static void Main() 
    {
        string path = @"c:\temp\MyTest.txt";
        string path2 = path + "temp";

        try 
        {
            // Create the file and clean up handles.
            using (FileStream fs = File.Create(path)) {}

            // Ensure that the target does not exist.
            File.Delete(path2);

            // Copy the file.
            File.Copy(path, path2);
            Console.WriteLine("{0} copied to {1}", path, path2);

            // Try to copy the same file again, which should succeed.
            File.Copy(path, path2, true);
            Console.WriteLine("The second Copy operation succeeded, which was expected.");
        } 

        catch 
        {
            Console.WriteLine("Double copy is not allowed, which was not expected.");
        }
    }
}

【讨论】:

    【解决方案5】:

    如果方法没有抛出异常,则表示它已经成功。

    【讨论】:

    • 但我需要以编程方式进行。是否可以检查没有发生异常
    • @Adban,当然,如果抛出异常,有两种可能性:要么处理它(使用 try/catch),要么让它传播,在这种情况下你的程序会崩溃。
    • @Adban:您对 C# 和异常的熟悉程度如何?如果您不确定如何查看是否发生了异常,可能值得多阅读一些书籍 - 不要试图跳过这个 File.Copy 电话 - 了解更多关于异常的信息一般.
    • @JonSkeet:我知道如何很好地使用 SEH,但我想问的是如何将“无例外”作为条件。
    • @Adban:嗯,你把方法调用放在了 try/catch 块中——如果你没有碰到 catch 块,它就不会抛出异常......(例如,你return true; 可能在 try 块内的 File.Copy 调用之后和 catch 块中的 return false; 之后,如果您只需要一个无论成功与否都会返回的方法。)
    猜你喜欢
    • 2011-08-10
    • 2010-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多