27

In the QFile::copy documentation it says

If a file with the name newName already exists, copy() returns false (i.e., QFile will not overwrite it).

But I need to copy a file even if the destination exists. Any workaround available in Qt for that?

Deleting the file is the obvious solution but it invites a race condition...

sashoalm
  • 75,001
  • 122
  • 434
  • 781

4 Answers4

43
if (QFile::exists("/home/user/dst.txt"))
{
    QFile::remove("/home/user/dst.txt");
}

QFile::copy("/home/user/src.txt", "/home/user/dst.txt");
GPPK
  • 6,546
  • 4
  • 32
  • 57
karlphillip
  • 92,053
  • 36
  • 243
  • 426
17

The obvious solution is of course to delete the file if it exists, before doing the copy.

Note however that doing so opens up the code to a classic race condition, since on a typical multitasking operating system a different process could re-create the file between your applications' delete and copy calls. That would cause the copy to still fail, so you need to be prepared (and perhaps re-try the delete, but that might introduce a need for count so you don't spend forever attempting, and on and on).

unwind
  • 391,730
  • 64
  • 469
  • 606
  • 4
    This answer is correct - but there's some irony here. [The actual code for `QFile::copy()` itself](https://github.com/radekp/qt/blob/6f5fb0be85b1d7cc9f93b615b5034c882e946301/src/corelib/io/qfile.cpp#L848) has a race condition. – Nathan Osman Jan 22 '16 at 03:31
6

The simplest retrying I can think of is:

while !QFile::copy("/home/user/src.txt", "/home/user/dst.txt")
{
    QFile::remove("/home/user/dst.txt");
}

But this still isn't a real solution as some of the race conditions are things that don't block remove.

I'm currently hunting for a way to handle writing a web page as an output but without the auto refresh ever catching between the remove and the copy.

LovesTha
  • 1,663
  • 1
  • 14
  • 17
  • 7
    Imagine you don't have file-permissions to do copy/remove. Now you have an infinite loop. – R.B. May 24 '18 at 17:29
4

Just call remove() before calling copy()

Riho
  • 4,523
  • 3
  • 33
  • 48