10

If the source directory and the target directory, MoveFile would actually make a copy of the source file into the target file, which means that I will end up seeing two files.

Is that the best way that rename can be achieved?

cpx
  • 17,009
  • 20
  • 87
  • 142
tom
  • 14,273
  • 19
  • 65
  • 124
  • 1
    What exactly do you mean? `MoveFileEx` with `MOVEFILE_COPY_ALLOWED` will not give you two files - it calls CopyFile then DeleteFile if the two files are on different volumes. – wj32 Dec 22 '10 at 20:55
  • I think I've seen instances where MoveFile() will do CopyFile() + DeleteFile(), but the source file is still locked by somebody so it's status will be set to Delete Pending; then when it gets unlocked it magically disappears. Or maybe I am making this up; can't remember. – Luke Dec 22 '10 at 21:06
  • If the program crashes or power is lost, non-atomic Moves (AKA copy-delete) may result in inconsistency. – unixman83 Sep 22 '11 at 01:38
  • See SetFileInformationByHandle < https://stackoverflow.com/questions/36450222/moving-a-file-using-setfileinformationbyhandle> – ianfun Jul 11 '22 at 13:11
  • Or my gist – ianfun Jul 11 '22 at 14:08

4 Answers4

11

The MoveFile function is indeed what you want. From the documentation:

The MoveFile function will move (rename) either a file or a directory (including its children) either in the same directory or across directories.

If the source and destination locations are both on the same volume, then an atomic rename operation is performed. If they're on different volumes, then a copy/delete operation is done instead (this is the best you can do).

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • 3
    `MoveFileEx` by default only moves, it will **not copy** unless you pass `MOVEFILE_COPY_ALLOWED` flag. – unixman83 Sep 22 '11 at 01:37
4

Try

#include <stdio.h>

int Result = rename( oldname , newname );

if (Result)
   // "Error occurred." );
else
   // "File was successfully renamed!";
cpx
  • 17,009
  • 20
  • 87
  • 142
1

What does your code look like? I have this:

if(MoveFile(_T("c:\\hold\\source"),_T("c:\\hold\\dest")))
{
    printf("succeeded\n");
}else
{
    printf("Error %d\n",GetLastError());
}

and it does not leave the source behind.

weloytty
  • 5,808
  • 5
  • 28
  • 35
0

You might want to try using the MoveFileEx() API without specifying the MOVEFILE_COPY_ALLOWED to see if that provides the behavior you're looking for.

Michael Burr
  • 333,147
  • 50
  • 533
  • 760
  • 1
    Not specifying MOVEFILE_COPY_ALLOWED simply means that cross-volume moves will fail. This is not what the OP wants. The "simulate by Copy/Delete" refers to the fact that cross-volume moves cannot be performed by simply re-writing the disk meta data as is done for same-volume moves. – David Heffernan Dec 22 '10 at 18:34
  • @David: I thought the OP was asking for a rename operation that only succeeded if it could be done by changing only the file metadata instead of a copy/delete rename simulation (I guess the question is a bit unclear to me). – Michael Burr Dec 22 '10 at 20:30
  • Well to be fair, the question is posed extremely poorly so, as is so often the case, one can only guess as to what the intent was. Perhaps your interpretation is correct! – David Heffernan Dec 22 '10 at 20:34