Abhijeet
Abhijeet

Reputation: 13856

C# code to copy files, can this snippet be improved?

While copying around 50 GB of data via local LAN share, due to connectivity issue copy failed at around 10 GB copied.

I have renamed copied 10GB of data directory to localRepository and then written a C# program to copy files from the remote server to destination, only if it is not found in local repository. If found move file from local repository to destination folder.

Although the code worked fine and accomplishes the task very well. I wonder, have I written the most efficient code? Can you find any improvements?

string destinationFolder = @"C:\DataFolder";
        string remoteRepository = @"\\RemoteComputer\DataFolder";
        string localRepository = @"\\LocalComputer\LocalRepository";

        protected void Page_Load(object sender, EventArgs e)
        {
            foreach (string remoteSrcFile in Directory.EnumerateFiles(remoteRepository, "*.*", SearchOption.AllDirectories))
            {
                bool foundInLocalRepo = false; ;
                foreach (var localSrcFile in Directory.EnumerateFiles(localRepository, "*.*", SearchOption.AllDirectories))
                {

                    if (Path.GetFileName(remoteSrcFile).Equals(Path.GetFileName(localSrcFile)))
                    {
                        FileInfo localFile = new FileInfo(localSrcFile);
                        FileInfo remoteFile = new FileInfo(remoteSrcFile);

                        //copy this file from local repository
                        if (localFile.Length == remoteFile.Length)
                        {
                            try
                            {
                                File.Move(localSrcFile, PrepareDestinationPath(remoteSrcFile));
                                Debug.WriteLine(remoteSrcFile + " moved from local repo");
                            }
                            catch (Exception ex)
                            {
                                Debug.WriteLine(remoteSrcFile + " did not move");
                            }
                            foundInLocalRepo = true;
                            break;
                        }
                    }
                }
                if (!foundInLocalRepo)
                {
                    //copy this file from remote repository
                    try
                    {
                        File.Copy(remoteSrcFile, PrepareDestinationPath(remoteSrcFile), false);
                        Debug.WriteLine(remoteSrcFile + " copied from remote repo");
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine(remoteSrcFile + " did not copy");
                    }

                }
            }
        }

        private string PrepareDestinationPath(string remoteSrcFile)
        {
            string relativePath = remoteSrcFile.Split(new string[] { "DataFolder" }, StringSplitOptions.None)[1];
            string copyPath = Path.GetFullPath(destinationFolder + relativePath);
            Directory.CreateDirectory(Path.GetDirectoryName(copyPath));
            return copyPath;
        }

EDIT:

Based on answer given by Thomas I am attempting to zip the file. Traditionally as an end user we use to zip a file and then copy. As a programmer can we zip and copy the file parallel? I mean the portion which has been zipped send it over the wire?

Upvotes: 1

Views: 743

Answers (2)

Thomas
Thomas

Reputation: 1563

I would suggest zipping the files before moving. Try take a look at the very simple http://dotnetzip.codeplex.com/

Try zipping 1000 files a time, in that way, you don't have to run the for-loop that many times and establish new connections etc each time.

Upvotes: 1

Matthew Watson
Matthew Watson

Reputation: 109547

You are doing far too much work with the nested loop.

You should remove the inner "foreach" and replace it with some code that:

(1) Constructs the name of the file that you are looking for and

(2) Uses File.Exists() to see if exists, then

(3) Continues with the same block of code that you currently have following the "if (Path.GetFileName(remoteSrcFile)..." condition.

Something like this:

foreach (string remoteSrcFile in Directory.EnumerateFiles(remoteRepository, "*.*", SearchOption.AllDirectories))
{
    string localSrcFile = Path.Combine(localRepository, Path.GetFileName(remoteSrcFile));

    if (File.Exists(localSrcFile))
    {
        ...
    }
}

Upvotes: 2

Related Questions