Coping files and folders

monarch_dodra monarchdodra at gmail.com
Thu Jan 24 00:58:05 PST 2013


On Thursday, 24 January 2013 at 07:41:23 UTC, Jacob Carlborg 
wrote:
> On 2013-01-24 07:28, Joel wrote:
>> How does one copy folders (with files in them) including sub 
>> folders,
>> and creating any needed folders?
>>
>> Like:
>> land\house\cat.d
>> land\house\rat.exe
>> land\house\bedroom\ants.txt
>>
>> to
>> root\island\house\cat.d
>> root\island\house\rat.exe
>> root\island\house\bedroom\ants.txt
>>
>> One work around is to use 'system' (under std.process).
>
> I don't think Phobos currently has any functions for this. 
> Someone posted code in these newsgroups of a parallel 
> implementation of copy and remove.

Mustn't be very hard to manually write "copyDir".

The problem with "copyDir" is its transactional behavior: What 
should it do in case of a failure mid copy? Bail? Cleanup? 
Continue?

Anyways, I just threw this together. The first version bails on 
first error.
The second version keeps going as much as it can, and returns 
true on success.

The caller is then free to (or not to) call rmdirRecurse in case 
of failure.

//Throws exception on first error.
void copyDir(string inDir, string outDir)
{
     if (!exists(outDir))
         mkdir(outDir);
     else
         if (!isDir(outDir))
             throw new FileException(format("Destination path %s 
is not a folder.", outDir));

     foreach (entry; dirEntries(inDir.idup, SpanMode.shallow))
     {
         auto fileName = baseName(entry.name);
         auto destName = buildPath(outDir, fileName);
         if (entry.isDir())
             copyDir(entry.name, destName);
         else
             copy(entry.name, destName);
     }
}

//Silently keeps going as much as it can, then returns true on 
success,
//or false if an error occured.
bool copyDirSilent(string inDir, string outDir)
{
     if (!exists(outDir))
     {
         auto e = collectException(mkdir(outDir));
         if (e !is null)
             return false;
     }
     else
         if (!isDir(outDir))
             return false;

     foreach (entry; dirEntries(inDir, SpanMode.shallow))
     {
         auto fileName = baseName(entry.name);
         auto destName = buildPath(outDir, fileName);
         if (entry.isDir())
         {
             bool b = copyDirSilent(entry.name, destName);
             if (b == false)
                 return false;
         }
         else
         {
             auto e = collectException(mkdir(outDir));
             if (e !is null)
                 return false;
         }
     }
     return true;
}


More information about the Digitalmars-d-learn mailing list