9

我正在尝试使用 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,这是否确保移动操作将是原子性的,还是有另一种方法来实现这种原子性?

4

4 回答 4

14

根据 MSDN 博客文章How to do atomic writes in a file,重命名 NTFS 文件是一个原子操作:

解决方案?让我们记住元数据更改是原子的。重命名就是这样的情况。因此,我们可以只执行对临时文件的写入,并且在我们知道写入在磁盘上(完成并刷新)之后,我们可以将旧文件与新文件互换。

当然,这并不能保证File.Move只发出 NTFS 重命名操作,但我想不出它应该做更复杂的事情的正当理由。

于 2013-03-07T15:30:57.060 回答
4

如果源和目标位于同一卷上,则 File.Move 应该是“重命名”。因此,无论文件大小如何,移动都应该是“即时的”。我想这是你的担心?

来自 MS 员工的常见问题解答http://msdn.microsoft.com/en-gb/library/windows/desktop/aa365240%28v=vs.85%29.aspx我们有;

'常见问题:如果现有文件和新文件都在同一个驱动器上,MoveFileEx 是原子的吗?

简单的答案是“通常,但在某些情况下,它会默默地退回到非原子方法,所以不要指望它”。

我想如果它是 100% 关键的,你可以看看 Transactional NTFS。我不确定.Net 中是否有包装器,因此您可能需要使用 P/Invoke。

于 2013-03-07T15:23:45.957 回答
1

This is a feature of windows, rather than c# or the .Net Framework.

See here

Atomicity of File.Move

于 2013-03-07T15:29:35.033 回答
0

您可以将文件直接写入目标,并使用在大文件准备好后创建的零大小信号文件。您的阅读器进程可以查找信号文件并在信号文件可用后读取一个巨大的文件。我认为这可以解决“原子性”问题。

于 2013-03-07T16:30:41.107 回答