5

我有一个项目作为计划任务每​​ 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 的图像数据(数百万张图像)可能会有帮助,也可能没有帮助。

4

3 回答 3

5

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

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

1000 次File.Copy使用覆盖设置为 false 在try, catch317.13 毫秒

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

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

1000 次File.Copy使用覆盖设置为 false 在try, catch14758.74 毫秒

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

于 2013-10-24T23:27:00.310 回答
2

使用第一种情况,您更有可能看到更好的性能(尽管请确保将调用包装File.Copy在 a 中try..catch,因为如果文件确实存在,它将抛出一个IOException。您的第一个示例让底层平台处理文件存在的检查,它可能会以您的代码无法优化的方式进行优化。由于每次调用在网络上的往返时间,大幅减少调用次数将提高性能。

此外,远程系统可能会在您调用File.Exists和之间发生变化File.Copy,后者可能会覆盖在您检查和开始复制之间创建的文件。

更好的方法是首先在远程机器上创建一个文件列表,然后只复制不存在的文件。当您执行此复制时,请使用您的第一种方法与try..catch. 这可确保您不会浪费时间尝试复制开始时存在的文件,并确保您不会意外覆盖开始复制内容后创建的文件。

于 2013-10-24T23:11:34.603 回答
0

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

这样,只有一个网络 ls 等效操作,并且只有您需要的尽可能多的复制操作。

于 2013-10-24T23:04:02.810 回答