如何在C#中仅复制新文件或修改过的文件 [英] How to copy only new or modified files in C#

查看:132
本文介绍了如何在C#中仅复制新文件或修改过的文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道这可能已经完成并讨论了很多次,但我找不到我要找的答案。



我正在努力创建一个C#中简单的目录/文件复制控制台应用程序。我需要的是将所有文件夹和文件(保持原始层次结构)从一个驱动器复制到另一个驱动器,例如从驱动器C:\ Data复制到驱动器E:\ Data。



但是,我只希望它将任何NEW或MODIFIED文件从源复制到目的地。

如果目的地上的文件驱动器比源驱动器上的驱动器更新,然后它不会复制。



(问题)

在我的代码中,它将源中的文件abc.pdf与目标中的文件xyz.pdf进行比较,因此即使目标文件较新,也会使用源中的任何内容覆盖目标文件。我试图弄清楚如何使它将源中的abc.pdf与目的地中的abc.pdf进行比较。

T如果我将源和目标向下钻取到特定文件,他的工作,但当我退回到文件夹级别时,它会用源文件覆盖目标文件,即使目标文件较新。



(我的解决方案 - 没有用)

我想通过放if(file.LastWriteTime> destination.LastWriteTime) )在foreach命令之后,它将比较两个文件夹中的文件,File1源到File1目的地,但事实并非如此。



似乎我在FileInfo [],foreach或if语句中遗漏了一些内容,使其成为一对一的比较。我想可能会引用Path.Combine语句或SearchOption.AllDirectories,但我不确定。



有什么建议吗?

从我的基本代码示例中可以看出,我是C#的新手,所以请简单回答一下条款。



谢谢。

以下是我尝试过的代码,但它不起作用。



我尝试过:



I know this has probably been done and discussed umpteen times, but I can’t find the answer I am looking for.

I am trying to create a simple "directory/file copy" console application in C#. What I need is to copy all folders and files (keeping the original hierarchy) from one drive to another, like from drive C:\Data to drive E:\Data.

However, I only want it to copy any NEW or MODIFIED files from the source to the destination.
If the file on the destination drive is newer than the one on the source drive, then it does not copy.

(the problem)
In the code I have, it's comparing file "abc.pdf" in the source with file "xyz.pdf" in the destination and thus is overwriting the destination file with whatever is in the source even though the destination file is newer. I am trying to figure out how to make it compare "abc.pdf" in the source to "abc.pdf" in the destination.
This works if I drill the source and destination down to a specific file, but when I back out to the folder level, it overwrites the destination file with the source file, even though the destination file is newer.

(my solutions – that didn’t work)
I thought by putting the "if (file.LastWriteTime > destination.LastWriteTime)" after the "foreach" command, that it would compare the files in the two folders, File1 source to File1 destination, but it’s not.

It seems I’m missing something in either the "FileInfo[]", "foreach" or "if" statements to make this a one-to-one comparison. I think maybe some reference to the "Path.Combine" statement or a "SearchOption.AllDirectories", but I’m not sure.

Any suggestions?
As you can see from my basic code sample, I'm new to C# so please put your answer in simple terms.

Thank you.
Below is the code I have tried, but it’s not working.

What I have tried:

class Copy  
{  
    public static void CopyDirectory(DirectoryInfo source, DirectoryInfo destination)  
    {  
        if (!destination.Exists)  
        {  
            destination.Create();  
        }  
        // Copy files.  
        FileInfo[] files = source.GetFiles();  
        FileInfo[] destFiles = destination.GetFiles();  
        foreach (FileInfo file in files)  
            foreach (FileInfo fileD in destFiles)  
                // Copy only modified files    
                    if (file.LastWriteTime > fileD.LastWriteTime)  
                    {  
                        file.CopyTo(Path.Combine(destination.FullName,  
                        file.Name), true);  
                    }  

                // Copy all new files  
                else  
                if (!fileD.Exists)  
                {  
                    file.CopyTo(Path.Combine(destination.FullName, file.Name), true);  
                }  
        // Process subdirectories.  
        DirectoryInfo[] dirs = source.GetDirectories();  
        foreach (DirectoryInfo dir in dirs)  
        {  
            // Get destination directory.  
            string destinationDir = Path.Combine(destination.FullName, dir.Name);  
            // Call CopyDirectory() recursively.  
            CopyDirectory(dir, new DirectoryInfo(destinationDir));  
        }  
    }  
}  

推荐答案

您只是比较日期,而不是文件名。 (摆脱那个内循环)。



对destFiles.ToList()执行.SingleOrDefault()调用,以检查给定源文件名的目标文件。



如果找不到,那就是新的;否则比较日期。
You're only comparing dates, not file names. (Get rid of that "inner loop").

Do a .SingleOrDefault() call on destFiles.ToList() to check for a destination file given a source file name.

If it doesn't find it, it's new; else compare the dates.


在这一行之后:
foreach (FileInfo fileD in destFiles) 

你应该首先比较文件名的相等性,然后才进行复制:

you should first compare the file names for equality, and only then do the copying:

If (file.Name.equals(fileD.Name))
{
// your code ...
}

如果您想要更高级的东西,您可以尝试使用LINQ的Gerry解决方案。

If you want something more advanced you could try Gerry's solution which involves using LINQ.


更新:



我用上面的建议修改了我的代码,一切顺利。它完全符合我的预期。



但是,我遇到的问题是在大文件夹上运行应用程序所花费的时间。 (包含6,000个文件和5个子文件夹)



在一个小文件夹中,(5个子文件夹中有28个文件)只需几秒钟即可运行。但是,在较大的文件夹上,只需35分钟即可处理1,300个文件。



解决方案:



下面的代码会做同样的事情但速度要快得多。这个新版本在大约10秒内处理了6,000个文件。它在大约1分50秒内处理了40,000个文件。



这个新代码做了什么(不做)



如果目标文件夹为空,则将所有文件从源复制到目的地。



如果目的地有部分或全部相同的文件/文件夹作为源,比较和复制从源到目的地的任何新的或修改过的文件。



如果目标文件比源文件新,请不要复制。



所以,这是实现它的代码。享受和分享。



感谢所有帮助我更好地理解这一点的人。



Update:

I modified my code with the suggestions above and all went well. It did exactly as I expected.

However, the problem I ran into was the amount of time it took to run the application on a large folder. (containing 6,000 files and 5 sub-folders)

On a small folder, (28 files in 5 sub-folders) it only took a few seconds to run. But, on the larger folder it took 35 minutes to process only 1,300 files.

Solution:

The code below will do the same thing but much faster. This new version processed 6,000 files in about 10 seconds. It processed 40,000 files in about 1 minute and 50 seconds.

What this new code does (and doesn’t do)

If the destination folder is empty, copy all from the source to the destination.

If the destination has some or all of the same files / folders as the source, compare and copy any new or modified files from the source to the destination.

If the destination file is newer than the source, don’t copy.

So, here’s the code to make it happen. Enjoy and share.

Thanks to everyone who helped me get a better understanding of this.

using System;
    using System.IO;


    namespace VSU1vFileCopy
    {
        class Program
        {
            static void Main(string[] args)
            {
                const string Src_FOLDER = @"C:\Data";
                const string Dest_FOLDER = @"E:\Data";
                string[] originalFiles = Directory.GetFiles(Src_FOLDER, "*", SearchOption.AllDirectories);

                Array.ForEach(originalFiles, (originalFileLocation) =>
                {
                    FileInfo originalFile = new FileInfo(originalFileLocation);
                    FileInfo destFile = new FileInfo(originalFileLocation.Replace(Src_FOLDER, Dest_FOLDER));

                    if (destFile.Exists)
                    {
                        if (originalFile.Length > destFile.Length)
                        {
                            originalFile.CopyTo(destFile.FullName, true);
                        }
                    }
                    else
                    {
                        Directory.CreateDirectory(destFile.DirectoryName);
                        originalFile.CopyTo(destFile.FullName, false);
                    }
                });
            }
        }
    }


这篇关于如何在C#中仅复制新文件或修改过的文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆