File.Copy()如果​​文件可能已存在则性能

时间:2013-10-24 22:55:56

标签: c# performance file file-io copy

我有一个项目,每5分钟作为一个计划任务运行。除此之外,该项目还会运行数百个图像,并以这种方式将它们复制到网络驱动器中。

foreach (string file in Files)
{
    string Control = Path.GetFileNameWithoutExtension(file);
        File.SetAttributes(file, FileAttributes.Normal);
        try
        {
            File.Copy(file, destinationFolder + "\\" + Control + @".pdf", false);
        }
        catch (Exception err)
        {
            Console.Writeline(err.ToString());
        }
}

“false”参数当然告诉它不要覆盖文件(如果文件已经存在)。

这比首先检查文件是否已经存在更快/更好的做法,然后只有在文件不存在时才复制? (见下文)

foreach (string file in Files)
{
    if (File.Exists(destinationFolder + "\\" + ControlNumber + ".pdf") == false)
    {
        File.SetAttributes(file, FileAttributes.Normal);
        File.Copy(file, destinationFolder + "\\" + ControlNumber + @".pdf");
    }
}

我的直觉告诉我,第一种是更好的方法。但是,我对编程比较陌生,并且很想知道哪个更好,更快,更广泛接受等等。

谢谢!

编辑: 知道我要复制的远程驱动器/文件夹包含4TB的图像数据(数百万张图像)可能有用也可能没有帮助

3 个答案:

答案 0 :(得分:5)

在本地驱动器上对此进行了测试,结果如下:

检查文件是否存在1000次,如果不存在则执行File.Copy 28.29毫秒

File.Copy中将覆盖设置为false的try, catch执行1000次: 317.13毫秒

在网络驱动器上测试,结果如下:

检查文件是否存在1000次,如果不存在则执行File.Copy 203.48毫秒

File.Copy中将覆盖设置为false的try, catch执行1000次: 14758.74毫秒

基于此,我认为首先进行文件检查会更有效率。

答案 1 :(得分:2)

使用第一种情况你更有可能看到更好的性能(尽管确保将调用包裹在File.Copy中的try..catch,因为它会抛出IOException文件确实存在。你的第一个例子让底层平台处理文件存在的检查,它可以以你的代码所不能的方式进行优化。由于你做的每次通话都在网络上的往返时间,大大减少了电话会有性能提升。

此外,远程系统可能会在您对File.ExistsFile.Copy的调用之间进行更改,而后者可能会覆盖在您检查和开始复制之间创建的文件。

更好的方法是首先在远程计算机上创建文件列表,然后仅复制尚不存在的文件。执行此复制时,请使用try..catch的第一种方法。这样可以确保您不会浪费时间尝试复制启动时存在的文件,还可以确保不会意外覆盖在开始复制文件后创建的文件。

答案 2 :(得分:0)

这些都不是解决问题的最快方法。我要做的是在你的远程驱动器上进行Directory.GetFiles调用,比较结果,只复制你需要的文件。

这样,只有一个网络ls等效操作,只有你需要的复制操作。