我有一个项目,该项目每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的图像数据(百万张图像),可能有所帮助,也可能没有帮助。
在本地驱动器上进行了测试,结果如下:
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毫秒
基于此,我认为很明显,先执行文件检查会更高效。
[在第一种情况下,您更有可能看到更好的性能(尽管请确保将对File.Copy
的调用包装在try..catch
中,因为如果文件确实存在,它将抛出IOException
。您的第一个示例让底层平台处理文件是否存在的检查,这可能会以您的代码无法优化的方式进行优化,由于每次拨打电话的网络往返时间都大大减少了,因此可以提高性能。
此外,远程系统在您对File.Exists
和File.Copy
的调用之间可能会发生变化,并且后者可能会覆盖在您检查和开始复制之间创建的文件。
更好的方法是先在远程计算机上创建文件列表,然后仅复制尚不存在的文件。执行此复制时,将第一种方法与try..catch
一起使用。这样可以确保您不会浪费时间尝试复制开始时存在的文件,并且还可以确保不会意外覆盖在开始复制内容之后创建的文件。
这两个都不是解决问题的最快方法。我要做的是在远程驱动器上进行Directory.GetFiles
调用,比较结果,然后仅复制所需的文件。
这样,只有一个网络ls等效操作,并且只需要您所需的复制操作。