Why recursive directory copy does not exist, and why it should not.


This question comes up in internal discussion from time to time.


The reason is, the semantics of directory copy is not well defined. It largely depends on what you need. Here are some questions you need to answer before you go implement one:


1. Do you copy ACL?
2. Do you copy streams (NTFS supports multiple streams)?
3. What do you do if you encounter a reparse point?
4. What do you do with hard link?
5. What do you do on error?


There are probably many other questions need to be answered.


In the end, It is very difficult to implement one copy that fits everyone.

Comments (17)

  1. Andreas Häber says:

    What about many Directory.Copy overloads then? 🙂 Of course, this also means lot’s of testing etc.

    Maybe just giving a basic, shallow Directory.Copy method could fit most needs?

  2. Karl says:

    This may very well be over my head but aren’t there a number of other functions in .Net (and all other frameworks) that have to deal with multiple options and manage to pull it off?

    Couldn’t you offer overloaded methods? or a bitwise OR combination of an enumerator?

    I just don’t see how Directory.Copy() presents more unknown than say, Regex.Match

  3. Jerry Pisk says:

    1. No. File copy doesn’t do it so directory copy shouldn’t either.

    2. If the destination supports them you do. Again, file copy is straight forward on this.

    3 and 4. Valid points, the logical thing to do would be just create reparse point/hard link in the destination and point it to their original targets, but I’m sure that programmers who write code using their mouse would not understand the concept and complain that it’s not creating copies.

    5. Throw an exception 🙂 Cleanup would be an issue, especially if you managed to overwrite existing files.

    I’ll add one more: what do you do when a target directory exists? Do you just add files to it or do you overwrite it completely (so it will only contain files copied over but not the original files)?

    Still, those issues should be handled using parameters with no default values so everybody would have to lookup what the various options do and explicitly pick what they need.

  4. Dennis says:

    5. WinFS is supposed to be transactional, right? So do a rollback…

  5. Karl,

    The answer to this question from internal discussion is, if you need this functionality, roll your own implementation. Yes, this includes .Net framework components, and Microsoft components.

    Karl and Andeas,

    Offering overloaded methods or enumeration won’t work. There are many many behaviors people want. I don’t think it is possible to enumerate them all. Plus, one day the file system has new capabilities, how to you want to handle that?

    Karl,

    RegEx is well defined state machine. There is no ambiguity. While people definitely do want very different copy behaviors.

  6. Jerry Pisk says:

    Junfeng, every single of your arguments apply to file copies. Yet there is a File.Copy method. Would you please care to explain? Personally I don’t like the fact that File.Copy does not copy the original ACLs on the file or that it doesn’t copy alternate streams when it copies a file to a FAT file system. So either remove File.Copy or add Directory.Copy.

  7. File.Copy is such a basic thing that it has to be there. Today File.Copy is calling native Win32 CopyFile to do the actual copying. So whatever CopyFile offers, that is what File.Copy does.

    ACL support is considered in next version of .Net framework. So at least you can copy the ACL if you need. I don’t know about the stream support story. But as Microsoft moves to managed world, I suspect the support will be there.

    I have a theory that .Net framework supports whatever Win32 supports althought I can’t confirm it. Since Win32 does not have a directory copy, it is unlikely .Net framework will have one.

  8. I don’t see why you couldn’t have a FileCopyOptions class, with lots of sensible defaults, and a Directory.Copy method (and a File.Copy method) that take theseoptions as a parameter. Effectively, this would be a method equivalent of xcopy, which I’m sure would make a lot of people happy.

    It wouldn’t be simple System.IO – you’d have to do lots of additional things like ACL copies, audit setting copies, etc. But giving people access to full xcopy functionality (or the functionality of any other shell command) from code, without creating an external process, is a good thing long-term.

  9. It is all about resource and priority. Windows exists for more than 10 year. There is no directory copy API (well, at least in core file services). Java exists for long. Last time I check, they don’t even have a file copy API, let alone directory copy.

    Plus, if you make one API that complicated, you will easy get into trouble. But, let’s save the debate for another day.

  10. Ben Dover says:

    File.Move

    Where is File.Rename as using File.Move is just stupid really when all you are doing is renameing.

  11. When you move file across drives, it becomes copy and delete, not just renaming anymore.

    And of course, File.Move is not the answer to directory copy, as the original does not exist any more.

  12. Andreas Häber says:

    I’ve seen enumerations for more complex issues before 🙂

    Look at the classes for opening a file. There’s a lot of options there, but Directory.Copy needs more.

    Is it a breaking change to have more overloads to a method in a future version? (I assume a no to that answer below, but I could be wrong.. therefore the question ;))

    If a v1 of Directory.Copy supported most of what people normally use when copying a directory then everything is cool 🙂 and if lot’s of customers asks for more options then you could add that support in the next version.

    However, the first thing you should really do is ask lot’s of developers what behaviour they need when copying directories… and then you can see if there’s lot’s of common patterns.

    If yes then make those available in the next version.

    If not then maybe it’s best to focus on other work or something else 🙂

  13. Ben Dover says:

    Yes im aware of that but they are 2 different logical actions so why not model it as that in the API?

  14. Willy Denoyette says:

    Directory copy is available through the System.Management classes using WMI’s Win32_Directory class methods Copy and CopyEx. Other methods of the class make it possible to change ownership and change the security settings. I know not all questions are answered by this, but it could be something to start with.

  15. As I was reading Microsoft public newsgroup, I find another request about file copying.

    1. Confirmation on overwrite.

    2. Continue copying on other files while waiting for confirmation on overwrite.

    You see, the different kinds of request can go on and on.