c# file move and overwrite [duplicate]

旧时模样 提交于 2021-01-13 08:59:05

问题


I'm developing a multi threaded application. I have somewhere in my code :

File.Delete(sidetapedata);
File.Move(sidetapedata2, sidetapedata); //sidetapedata and sidetapedata2 are two file paths that correspond to sidetapedata.txt and sidetaptdata2.txt in some directory.

The second line sometimes runs fine and other times, it throws an IOException :

Cannot create a file when that file already exists.

There is one more thread that is accessing the sidetapedata file but that one is only reading this file, no write operations. I am using locks to protect race conditions. Don't know why this is happening.

UPDATE : even when visual c# debugger shows me this exception, looking into the directory that contains these files, I see there is no sidetapedata.txt file but there is a sidetapedata2.txt file!

UPDATE2 : Also, this behavior only happens when sidetapedata.txt and sidetapedata2.txt are both blank


回答1:


Not sure why this would happen unless there's some event triggered in the file system by the Delete call which means it's not actually deleted until slightly after the call returns. A few options:

  • You could loop (with some sort of maximum number of loops before erroring) where you check for the file's existence before trying the move, and sleep briefly if it still exists after deletion
  • You could use File.Copy(sidetapedata, sidetapedata2, true) to copy instead of moving, and then delete the source file. This will be less efficient though, assuming the move would be handled by a simple file system directory entry change (rather than really copying the data)
  • You could use File.Move on the target file instead of File.Delete to move it to some harmless other filename, then delete that afterwards, hoping that the Move is more atomic than the Delete.

I suspect the threading is irrelevant here - I suggest you write a short but complete program to validate that, so you can rule it out (and easily test the workarounds).




回答2:


I am unsure if this is the same for .NET, but according to the win32 DeleteFile api reference:

The DeleteFile function marks a file for deletion on close. Therefore, the file deletion does not occur until the last handle to the file is closed.

So there is probably a window of time between the call to Delete returning and Windows closing the last handle to the file. It looks like you are calling Move during this period of time.




回答3:


In .NET Core 3.0 and later versions, you can call Move(String, String, Boolean) setting the parameter overwrite to true, which will replace the file if it exists.

see https://docs.microsoft.com/en-us/dotnet/api/system.io.file.move?view=netcore-3.0




回答4:


As per this answer : use FileStream with FileShare

FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.None);


来源:https://stackoverflow.com/questions/8776395/c-sharp-file-move-and-overwrite

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!