parallel copy directory, faster than robocopy

Jay Norwood jayn at prismnet.com
Mon Feb 13 21:39:08 PST 2012


ok, I didn't test that first one very well.  It worked for directory copies, but I didn't test non directories.  So here is the fixed operation for non directories, where it just copies the single file.  

So it now does two cases:
copy regular_file destinationDirectory
copy folder destinationDirectory

What I'd like to add is wildcard support for something like 
 copy folder/* destinationDirectory

I suppose also it could be enhanced to handle all the robocopy options, but I'm just trying out the copy speeds for now.


module main;

import std.stdio;
import std.file;
import std.path;
import std.datetime;
import std.parallelism;

int main(string[] argv)
{
 	if (argv.length != 3){
 		writeln ("need to specify src and dest dir");
 		return 0;
 	}

	// TODO expand this to handle wildcard

 	string dest = argv[$-1];
 	foreach(string dir; argv[1..$-1])
	{
		writeln("copying directory: "~ dir );
		auto st1 = Clock.currTime(); //Current time in local time.
		cpdir(dir,dest); 
 		auto st2 = Clock.currTime(); //Current time in local time.
		auto dif = st2  - st1 ;
		auto ts= dif.toString();
		writeln("time:"~ts);
	}
	writeln("finished !");
	return 0;
}
void cpdir(in char[] pathname ,in char[] dest){
    DirEntry deSrc = dirEntry(pathname);
	string[] files;

	if (!exists(dest)){
		mkdir (dest); // makes dest root
	}
 	DirEntry destDe = dirEntry(dest);
	if(!destDe.isDir()){        
		throw new FileException( destDe.name, " is not a directory"); 
	}
	string destName = destDe.name ~ '/';
	string destRoot = destName ~ baseName(deSrc.name);

	if(!deSrc.isDir()){
		copy(deSrc.name,destRoot); 
	}
	else    { 
		string srcRoot = deSrc.name;
		int srcLen = srcRoot.length;
        mkdir(destRoot);
		
		// make an array of the regular files only, also create the directory structure
		// Since it is SpanMode.breadth, can just use mkdir
 		foreach(DirEntry e; dirEntries(deSrc.name, SpanMode.breadth, false)){
			if (attrIsDir(e.linkAttributes)){
				string destDir = destRoot ~ e.name[srcLen..$];
				mkdir(destDir);
			}
			else{
				files ~= e.name;
			}
 		} 

		// parallel foreach for regular files
		foreach(fn ; taskPool.parallel(files)) {
			string dfn = destRoot ~ fn[srcLen..$];
			copy(fn,dfn);
		}
	}
}




More information about the Digitalmars-d-announce mailing list