views:

2665

answers:

4

On POSIX systems rename(2) provides for an atomic rename operation, including overwriting of the destination file if it exists and if permissions allow.

Is there any way to get the same semantics on Windows? I know about MoveFileTransacted() on Vista and Server 2008, but I need this to support Win2k and up.

The key word here is atomic... the solution must not be able to fail in any way that leaves the operation in an inconsistent state.

I've seen a lot of people say this is impossible on win32, but I ask you, is it really?

Please provide reliable citations if possible.

+2  A: 

you still have the rename() call on Windows, though I imagine the guarantees you want cannot be made without knowing the filesystem you're using - no guarantees if you're using FAT for instance.

However, you can use MoveFileEx and use the MOVEFILE_REPLACE_EXISTING and MOVEFILE_WRITE_THROUGH options. The latter has this description in MSDN:

Setting this value guarantees that a move performed as a copy and delete operation is flushed to disk before the function returns. The flush occurs at the end of the copy operation.

I know that's not necessarily the same as a rename operation, but I think it might be the best guarantee you'll get - if it does that for a file move, it should for a simpler rename.

gbjbaanb
To the best of my knowledge, if the destination existed and an I/O error occurs during the data copy step, this "original" destination is lost, thus MoveFileEx is not atomic per your requirements. That's why MoveFileTransacted was added later.
Martin Plante
+5  A: 

Win32 does not guarantee atomic file meta data operations. I'd provide a citation, but there is none - that fact that there's no written or documented guarantee means as much.

You're going to have to write your own routines to support this. It's unfortunate, but you can't expect win32 to provide this level of service - it simply wasn't designed for it.

Adam Davis
+2  A: 

In Windows Vista and Windows Server 2008 an atomic move function has been added - MoveFileTransacted()

Unfortunately this doesn't help with older versions of Windows.

[Edit] Interesting article here on MSDN: http://blogs.msdn.com/adioltean/archive/2005/12/28/507866.aspx

A: 

See ReplaceFile() in Win32.

For reference, see http://research.microsoft.com/pubs/64525/tr-2006-45.pdf

Ed
If you read http://msdn.microsoft.com/en-us/library/aa365512(VS.85).aspx you'll see that `ReplaceFile` is a complicated merge operation, with no indication that it's atomic.
Gabe