tags:

views:

1331

answers:

3

Hi,

The Windows API function CopyFile has an argument BOOL bFailIfExists that allows you to control whether or not you want to overwrite the target file if it exists.

The boost::filesystem copy_file function has no such argument, and will fail if the target file exists. Is there an elegant way to use the boost copy_file function and overwrite the target file? Or is it better to simply use the Windows API? My current target platform is Windows, but I prefer to use STL and boost where possible to keep my code platform independent.

Thank you.

+4  A: 

Test if the destination file exists first and if it does then remove it :

if (exists (to_fp))
    remove (to_fp);
copy_file (from_fp, to_fp);

Or if you're worried about the file appearing between the test and the copy then you could write to a temporary file and then rename it to the destination file.

jon hanson
Yes this is possible. But what if the copy operation fails? You already deleted the target. It doesn't have the same transaction-like semantics as CopyFile.
Dani van der Meer
Does the rename alternative not give you this?Anyway from looking at the boost source the API doesn't allow you to optionally overwrite the file. You could suggest this to them as an improvement. In the meantime you could take your own copy of the boost copy_file function and modify it to take an extra "overwrite" bool parameter.
jon hanson
Well, I guess the rename logic will work, but I was hoping there was something in the library that solves this, and that I won't have to solve it myself :). I will try to suggest it as an improvement. I think this is a logical and helpful feature. Anyway, thanks for your help. I will probably use CopyFile for now.
Dani van der Meer
Dani, the purpose to use boost is to write portable code, why to being so lazy you jeopardize the main reason to use boost ?
Gaetano Mendola
Portability is definitely an important reason for using Boost, but not necessarily the main reason. I would argue that the main reason for using a library like boost, but also the Windows API, is not having to implement basic functionality yourself (and test, debug, etc.). In this case these two reasons conflict, and I have to make the right trade-off. What is the right trad-off is of course a matter of opinion :).
Dani van der Meer
I decided to accept this answer, even though it is not a complete answer to the question. Apparently there is no better answer, and this answer describes the best approach.
Dani van der Meer
jon hanson
+1  A: 

Is there an elegant way to use the boost copy_file function and overwrite the target file?

Apparently there's no direct API to do this.

Or is it better to simply use the Windows API? My current target platform is Windows, but I prefer to use STL and boost where possible to keep my code platform independent.

From the documentation:

A proposal, N1975, to include Boost.Filesystem in Technical Report 2 has been accepted by the C++ Standards Committee. The Boost.Filesystem library will stay in alignment with the TR2 Filesystem proposal as it works its way through the TR2 process. Note, however, that namespaces and header granularity differs between Boost.Filesystem and the TR2 proposal.

Which strongly suggests that sticking with boost::filesystem is a good idea.

dirkgently
+2  A: 

There's a third enum argument to copy_file, boost::filesystem::copy_option::overwrite_if_exists

copy_file(source_path,destination_path,copy_option::overwrite_if_exists);
anno
Thanks anno. I wasn't aware of this. It seems that this option was added sometime between version 1.35 that I was using when I asked the question, and version 1.41 that I'm using now. I can't find the change in the change history of the library. But anyway, problem solved. I'm not sure if I should now accept your answer, maybe I'll ask on meta.
Dani van der Meer