Std API to copy a directory

Hi all. I'm quite surprised that I haven't found a decent answer to this yet, but I'm looking for an API in the standard library to copy a directory. I know I can create/remove directories, and I can copy files.

Thanks in advance!

It's because copying a directory is actually a more complicated task than you might think.

There are many options for how to do it:

  1. Copy by depth first or breath first?
  2. Do you want to use multi threading to speed it up?
  3. And if so, how would you choose the amount of threads and how do you pick which threads are copying files and which are walking directories?
  4. Do you want to make an actual copy of each file, or is a hard link okay?
2 Likes

Yea, that's a fair point. Although, these are simply choices that need to be made, just like any other API must do. For example, std::fs::remove_dir_all makes the choice of not following symbolic links but removes them. That's probably more of an obvious choice, but still.

I did just find the fs_extra crate, which makes an effort to address this, but it hasn't had any activity in a while and the documentation is lacking a bit. I'll look more into it.

In the meantime are there any other crates you might recommend for non-std file system operations?

Okay, so I think I found the biggest piece of the puzzle: https://github.com/BurntSushi/walkdir

I should be able to use walkdir to walk the directory I want to copy, and copy each entry to a new location.

To close this out, I see the answer to my initial question is, no - there's no directory copy API in std, and for good reason. Basically, it seems that the direction Rust wants to go with the std::fs library is still not completely flushed out, and thus is still quite conservative.

I'm only half joking here, but how about just shelling out to "cp"?

Command::new("cp")
    .arg("-r")
    .arg(src)
    .arg(dest)
    .output()?

I'm sure the Unix "cp" utility has had to tackle every edge case under the sun, and would be more resilient and "correct" than whatever std has had time to develop since Rust was created.

No, you're right that would definitely be one solution, but it assumes the environment is Unix-like and cp is available.