我正在尝试使用C#生成一个巨大的文本文件,另一个进程会不断查看该位置并尝试拾取该文件(如果可用)。
为了使下面的文件原子化是以下步骤:
1 - Write to file : Filename_temp.txt
2 - Check if Filename.txt already exists then Delete
3 - Do a File.Move to the same destination
From filename : Filename_temp.txt
TO : Filename.txt
由于C#没有重命名,我必须依赖File.Move,这是否确保移动操作是原子操作还是有另一种方法来实现这种原子性?
答案 0 :(得分:12)
根据MSDN博客文章How to do atomic writes in a file,重命名NTFS文件是原子操作:
解决方案?让我们记住元数据的变化是原子的。重命名就是这种情况。因此,我们可以只执行对临时文件的写入,并且在我们知道写入在磁盘上(已完成并刷新)之后,我们可以将旧文件与新文件交换。
当然,这并不能保证File.Move
只发出NTFS重命名操作,但我想不出它应该做更复杂的事情的正当理由。
答案 1 :(得分:4)
如果源和目标位于同一卷上,则File.Move应为'重命名'。因此,无论文件大小如何,Move都应该是“即时”的。我认为那是你关注的问题?
来自我们http://msdn.microsoft.com/en-gb/library/windows/desktop/aa365240%28v=vs.85%29.aspx的MS员工的常见问题解答
'常见问题:如果现有文件和新文件都在同一个驱动器上,MoveFileEx是否为原子?
简单的答案是“通常,但在某些情况下,它会默默地回归到非原子方法,所以不要指望它。”
我想如果它是100%的关键,你可以看看Transactional NTFS。我不确定.Net中是否有包装器,所以你可能需要使用P / Invoke。
答案 2 :(得分:1)
答案 3 :(得分:0)
您可以将文件直接写入目标,并使用在大文件准备就绪后创建的零大小信号文件。您的读者进程可以在信号文件可用后查找信号文件并读取大文件。我认为这可以解决“原子性”问题。