Brilliant! Thanks.

I think the silent one has errors. But I've used the first function in my program now. With mine, strait after doing the copying is was supposed then update a file, but didn't. Your one seems to work though.

On Thursday, 24 January 2013 at 08:58:06 UTC, monarch_dodra wrote:
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;
}

Reply via email to