2013-10-24 27 views
5

我有一个项目作为计划任务运行,每5分钟。除此之外,该项目通过数百个图像运行,并以这种方式将它们复制到网络驱动器中。File.Copy()性能如果文件可能已经存在

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()); 
     } 
} 

“假”的说法当然告诉它不覆盖文件,如果它已经存在。

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

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

http://ericlippert.com/2012/12/17/performance-rant/ –

+0

如果将所有现有文件的路径写入文本或xml文件中,然后检查是否更好首先列出,如果它不在该列表中,则复制到目录中,然后将新文件添加到列表中?只是一个想法:) –

+0

你是如何创建'文件'集合? –

回答

5

测试了这个结果如下本地驱动器上:

1000次检查文件是否存在,然后做一个File.Copy如果没有:28.29毫秒

1000次做有覆盖一个File.Copy设置为false在try, catch317.13毫秒

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

1000次检查文件是否存在,如果没有则执行File.Copy203。48毫秒

1000次做与覆盖集File.Copy,以虚假的try, catch14758.74毫秒

基于这一点,我会觉得很明显,首先进行文件检查会更有效。

+0

非常有趣,与反直觉接壤。在使用我的2个选项秒表后,我看到非常相似的结果。 – Milne

+0

在我的测试中,应该注意它正在尝试相同的文件,所以它每次都存在。 –

+0

我认为需要在这里添加的是,try/catch块需要大量的CPU来处理......它可能会减慢速度,但没关系。第二种方式好多了。 – Yuki

0

无论是那些很可能是最快的方法来解决这个问题。我要做的是在远程驱动器上拨打Directory.GetFiles,比较结果,只复制所需的文件。

这样,只有一个网络ls-equivalent操作,并且只有您需要的复制操作。

+1

远程驱动器是4TB大的数百万个图像文件。听起来有点低效。 – Milne

+1

@ColtonMilne你应该看看'rsync'及其算法。 –

+0

@ ta.speot.is感谢+1,rsync非常有趣,虽然比我想要的简单应用稍微复杂一些。 – Milne

2

你更可能看到使用第一种情况下更好的性能(虽然确保您缠绕呼叫File.Copytry..catch,因为它会抛出一个IOException如果文件不存在,你的第一个例子让底层平台处理文件存在的检查,它可以优化你的代码不能的方式,由于每次通话的网络往返时间,大大减少呼叫次数将会有性能增益

另外,远程系统可能会在您拨打File.ExistsFile.Copy的电话之间发生变化,而后者可能会覆盖您在检查和启动时间之间创建的文件复制。

更好的方法是先在远程机器上创建一个文件列表,然后只复制那些不存在的文件。当你做这个副本时,用你的第一个方法try..catch。这可以确保您不会浪费时间试图复制启动时存在的文件,并且确保您在开始复制事项后不会意外覆盖创建的文件。

+0

我看到你说有数百万个文件,但它们可能并不都在一个目录中。如果您将文件移动到的目录数量与文件数量相比较大(可能类似于1:5,但您必须进行配置以找到正确的数字),那么您只需使用第一种技术。如果目录数量很少,并且要复制的文件数量很大,那么您关心的每个目录中的所有文件名称的单次传输相对于您必须进行的往返次数尝试复制每个文件。 – seawolf

相关问题