File.Move()是否在IoException上删除原始文件?

时间:2018-08-21 22:40:56

标签: c# system.io.file

我有一个Web服务正在编写由其他程序读取的文件。

为了使阅读器程序在编写完成之前无法读取它们,我正在使用.tmp扩展名对其进行编写,然后使用File.Move将其重命名为.xml扩展名。

我的问题是,当我们批量运行时-短短几分钟内成千上万个文件。

我已经成功写入文件“ 12345.tmp”,但是当我尝试重命名它时,File.Move()会抛出IOException

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

异常:进程无法访问文件,因为正在使用该文件   通过另一个过程。

对于我的情况,我并不在乎文件名是什么,所以我重试:

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

异常:异常:找不到文件'12345.tmp'。

如果File.Move()在重命名文件时遇到错误,是否要删除源文件?

为什么?

是否有办法确保文件重命名成功或保持不变?

1 个答案:

答案 0 :(得分:2)

答案是,这很大程度上取决于文件系统本身的实现方式。同样,如果Move()在两个文件系统之间(甚至在两台机器之间,如果路径是网络共享),那么它也很大程度上取决于Move()的O / S实现。因此,保证将更少依赖于System.IO.File的工作,而更多地依赖于底层机制:O / S代码,文件系统驱动程序,文件系统结构等。

通常,在大多数情况下,Move()会按照您期望的方式运行:移动文件或保持原样。这是因为在单个文件系统中移动是从一个目录(磁盘数据结构)中删除文件 reference 并将其添加到另一个目录中的动作。如果发生问题,则将回滚该操作:通过相反的插入操作撤消从源目录中删除的操作。大多数现代文件系统都具有内置的日志记录机制,即使在操作过程中计算机断电的情况下,也可以确保完全执行移动操作或完全回滚移动操作。

话虽如此,但这仍然取决于,并非所有文件系统都提供这些保证。 See this study

如果您在Windows上运行,并且文件系统是本地的(不是网络共享),则可以使用Windows的Transacitonal File System (TxF) feature来确保移动操作的原子性。