擅长:python、mysql、java
<p>没有办法做到这一点;文件复制操作从来不是原子的,也没有办法实现它们。</p>
<p>但是你可以用一个随机的,临时的名字写这个文件,然后把它重命名。重命名操作必须是原子的。<s> 如果该文件已经存在,则重命名将失败,您将得到一个错误。</s></p>
<p><strong>[EDIT2]</strong><code>rename()</code>只有在同一个文件系统中执行时才是原子的。安全的方法是在目标文件夹中创建新文件。</p>
<p><strong>[编辑]</strong>关于重命名是否始终是原子的以及覆盖行为,有很多讨论。所以我挖掘了一些资源。</p>
<p>在Linux上,如果目标存在并且源和目标都是文件,那么目标将被自动覆盖(<a href="http://linux.die.net/man/2/rename" rel="noreferrer">man page</a>)。所以我错了。</p>
<p>但是<code>rename(2)</code>仍然保证,如果发生错误,原始文件或新文件将保持有效,因此该操作是原子的,因为它不会损坏数据。它不是原子的,因为它阻止两个进程同时执行相同的重命名,并且您可以预测结果。一个人会赢,但你不知道是哪一个。</p>
<p>在Windows上,如果另一个进程当前正在写入文件,则如果尝试打开该文件进行写入,则会出现错误,因此Windows的一个优点是。</p>
<p>如果在将操作写入磁盘时计算机崩溃,则文件系统的实现将决定损坏的数据量。应用程序对此无能为力。所以别再抱怨了:-)</p>
<p>也没有其他方法比这一个更好甚至更好。</p>
<p>你可以用文件锁定代替。但这只会让一切变得更加复杂,不会产生额外的优势(除了变得更加复杂,有些人确实认为这是一个巨大的优势,因为某些原因)。当你的文件在网络驱动器上时,你会添加很多漂亮的角盒。</p>
<p>可以将<code>open(2)</code>与模式<code>O_CREAT</code>一起使用,如果文件已经存在,则会使函数失败。但这不会阻止第二个进程删除文件并编写自己的副本。</p>
<p>或者可以创建一个锁目录,因为创建目录也必须是原子的。但那也买不到多少。你必须自己写锁定代码,并确保绝对,100%确保你真的,真的总是删除锁定目录,以防灾难-你不能</p>