[File.Copy()性能,如果文件已经存在

问题描述 投票:5回答:3

我有一个项目,该项目每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的图像数据(百万张图像),可能有所帮助,也可能没有帮助。

c# performance file file-io copy
3个回答
5
投票

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

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

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

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

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

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

基于此,我认为很明显,先执行文件检查会更高效。


2
投票

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

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

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


0
投票

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

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

© www.soinside.com 2019 - 2024. All rights reserved.