1

I would like to copy a file to an other, and I would like to use Boost::copy_file. It has a paramether called copy_option which can be:

  BOOST_SCOPED_ENUM_START(copy_option)
    {none, fail_if_exists = none, overwrite_if_exists};
  BOOST_SCOPED_ENUM_END

I have found another question regarding the overwrite_if_exists behaviour here: how to perform boost::filesystem copy_file with overwrite

My problem however is that I don't know how to use the fail_if_exists = none option. I would like to skip the copy operation, if the target file already exists.

I know its possible with if ( !exists(path) ) but I want to understand how does copy_option work.

How can I use fail_if_exists = none inside Boost::copy_file function?

Update: corrected the code, the one on boost doc website is kind of broken.

Community
  • 1
  • 1
hyperknot
  • 13,454
  • 24
  • 98
  • 153

2 Answers2

2

There is no copy_option to just skip the copy if the destination already exists.

But if (!exists(path)) copy_file(...) is not the right answer, either, because of the race condition: The file might be created between the time you perform the existence check and the time you attempt the copy. So even when you check for the file's existence, copy_file might fail.

The way to synthesize what you want is to catch the error and ignore it yourself. Something like this:

try {
    copy_file(...);
}
catch (const boost::system::system_error &err) {
    if (!err.code().equivalent(boost::system::errc::file_exists))
        throw;
}
Nemo
  • 70,042
  • 10
  • 116
  • 153
  • seems pretty inefficient to promote exceptions to normal workflow.. using variant returning error_code would be probably better – graywolf Sep 02 '15 at 11:14
0

This goes back to this proposal in order to allow for smoother transition of an old scoped-enum-hack to clean-c++0x-enum-classes:

 namespace FooEnum {
     enum type {
         SomeValue
     }
 }

Users could then write FooEnum::SomeValue and value-name collisions were avoided. C++0x will have native support for this.

So, you would just use <enum-name>::<enum-value>, i.e. copy_option::none etc.

Sebastian Mach
  • 38,570
  • 8
  • 95
  • 130