Follow @PDSAInc Copy New Files Only in .NET - Paul Sheriff's Blog for the Real World

Paul Sheriff's Blog for the Real World

This blog is to share my tips and tricks garnered over 25+ years in the IT industry

Paul's Favorites

Copy New Files Only in .NET

Recently I had a client that had a need to copy files from one folder to another. However, there was a process that was running that would dump new files into the original folder every minute or so. So, we needed to be able to copy over all the files one time, then also be able to go back a little later and grab just the new files.

After looking into the System.IO namespace, none of the classes within here met my needs exactly. Of course I could build it out of the various File and Directory classes, but then I remembered back to my old DOS days (yes, I am that old!). The XCopy command in DOS (or the command prompt for you pure Windows people) is very powerful. One of the options you can pass to this command is to grab only newer files when copying from one folder to another. So instead of writing a ton of code I decided to simply call the XCopy command using the Process class in .NET.

The command I needed to run at the command prompt looked like this:

XCopy C:\Original\*.* D:\Backup\*.* /q /d /y

What this command does is to copy all files from the Original folder on the C drive to the Backup folder on the D drive. The /q option says to do it quitely without repeating all the file names as it copies them. The /d option says to get any newer files it finds in the Original folder that are not in the Backup folder, or any files that have a newer date/time stamp. The /y option will automatically overwrite any existing files without prompting the user to press the "Y" key to overwrite the file.

To translate this into code that we can call from our .NET programs, you can write the CopyFiles method presented below.

C#

using System.Diagnostics

public void CopyFiles(string source, string destination)
{
  ProcessStartInfo si = new ProcessStartInfo();
  string args = @"{0}\*.* {1}\*.* /q /d /y";

  args = string.Format(args, source, destination);

  si.FileName = "xcopy";
  si.Arguments = args;
  Process.Start(si);
}

VB.NET

Imports System.Diagnostics

Public Sub CopyFiles(source As String, destination As String)
  Dim si As New ProcessStartInfo()
  Dim args As String = "{0}\*.* {1}\*.* /q /d /y"

  args = String.Format(args, source, destination)

  si.FileName = "xcopy"
  si.Arguments = args
  Process.Start(si)
End Sub

The CopyFiles method first creates a ProcessStartInfo object. This object is where you fill in name of the command you wish to run and also the arguments that you wish to pass to the command. I created a string with the arguments then filled in the source and destination folders using the string.Format() method. Finally you call the Start method of the Process class passing in the ProcessStartInfo object. That's all there is to calling any command in the operating system. Very simple, and much less code than it would have taken had I coded it using the various File and Directory classes.


Good Luck with your Coding,
Paul Sheriff

** SPECIAL OFFER FOR MY BLOG READERS **
Visit http://www.pdsa.com/Event/Blog for a free video on Silverlight entitled Silverlight XAML for the Complete Novice - Part 1.

 

Posted: Feb 02 2011, 11:36 PM by psheriff | with 4 comment(s)
Filed under:

Comments

Harry Lord said:

I love the old DOS commands! There are some things that are very hard to do outside of DOS like getting a list of files based on some basic criteria.

You may have overestimated the amount of code required to get the function to work:

public static void CopyFiles(string source, string destination)

{

   var sourceFiles = Directory.GetFiles(source);

   var destinationFiles = Directory.GetFiles(destination);

   foreach (var sourceFile in sourceFiles)

   {

       var destFileName = destination + "\\" + new FileInfo(sourceFile).Name;

       if (destinationFiles.Contains(destFileName) &&

           File.GetLastWriteTime(sourceFile) <=

             File.GetLastWriteTime(destinationFiles.First(x => x == destFileName)))

           continue;

       File.Copy(sourceFile, destFileName, true);

   }

}

Not too long and complicated.  Linq does help here though.

# February 3, 2011 10:33 AM

psheriff said:

Harry,

Yep, not too much more code. Another criteria I had was speed and I figured that XCopy would probably be faster than looping over files.

Thanks for the extra code!

Paul

# February 3, 2011 11:19 AM