Search code examples
c#system.io.file

Does File.Move() deletes original on IoException?


I have a webservice that is writing files that are being read by a different program.

To keep the reader program from reading them before they're done writing, I'm writing them with a .tmp extension, then using File.Move to rename them to a .xml extension.

My problem is when we are running at volume - thousands of files in just a couple of minutes.

I've successfully written file "12345.tmp", but when I try to rename it, File.Move() throws an IOException:

File.Move("12345.tmp", "12345.xml")

Exception: The process cannot access the file because it is being used by another process.

For my situation, I don't really care what the filenames are, so I retry:

File.Move("12345.tmp", "12346.xml")

Exception: Exception: Could not find file '12345.tmp'.

Is File.Move() deleting the source file, if it encounters an error in renaming the file?

Why?

Is there someway to ensure that the file either renames successfully or is left unchanged?


Solution

  • The answer is that it depends much on how the file system itself is implemented. Also, if the Move() is between two file systems (possibly even between two machines, if the paths are network shares) - then it also depends much on the O/S implementation of Move(). Therefore, the guarantees depend less on what System.IO.File does, and more about the underlying mechanisms: the O/S code, file-system drivers, file system structure etc.

    Generally, in the vast majority of cases Move() will behave the way you expect it to: either the file is moved or it remains as it was. This is because a Move within a single file system is an act of removing the file reference from one directory (an on-disk data structure), and adding it to another. If something bad happens, then the operation is rolled back: the removal from the source directory is undone by an opposite insert operation. Most modern file systems have a built-in journaling mechanism, which ensures that the move operation is either carried out completely or rolled back completely, even in case the machine loses power in the midst of the operation.

    All that being said, it still depends, and not all file systems provide these guarantees. See this study

    If you are running over Windows, and the file system is local (not a network share), then you can use the Transacitonal File System (TxF) feature of Windows to ensure the atomicity of your move operation.