.NET中的事务性打开/写入/替换?

时间:2011-09-24 00:05:50

标签: .net linux file transactions mono

我想也许我应该将它限制在8k。我想打开一个文件,每次都从头到尾写。但是,如果由于某种原因(比如断电)它没有完成我不想要损坏的数据。有没有办法我可以做一个事务文件打开/写/关闭所以它不会取代以前的文件,除非它成功?

当我谷歌时,我在数据库交易和ado而不是文件上获得了很多结果

3 个答案:

答案 0 :(得分:3)

  1. 写入临时文件
  2. 删除旧文件
  3. 仅在写入成功时重命名remporary文件。
  4. 如果在第二步之后但在第三步之前断电,为防止数据丢失,您还需要再做一步:

    • 在程序启动时,检查已删除主文件但尚未重命名的临时文件。如果找到,请再次对这些文件执行第三步。

答案 1 :(得分:2)

Windows Vista及更高版本中的NTFS是事务性的。

我不相信您可以从纯托管代码访问它 - 您需要P / Invoke到Win32 API。

一个好的起点是CreateTransactionCommitTransactionRollbackTransactionCreateFileTransacted(和其他*Transacted)Win32 API函数。

答案 2 :(得分:1)

我一直在使用的Mark Byer解决方案略有不同:

  1. 将新内容写入同一目录中的临时文件作为要替换的文件。
  2. 如果写入成功,请将[1]重命名为所需文件。
  3. 重命名是原子的,如果成功,则系统不会处于未定义状态。如果失败,那么,系统仍然处于原始状态 AND ,您需要在系统重启时备份您想要替换它的内容(在临时文件中)。

    我的典型命名约定是:

    /path/to/original/content.data

    /路径/到/原始/.# content.data

    如果系统在该过程中的某个地方关闭,那么在重新启动应用程序时,您可以扫描。#content.data,并将其显示给用户,就像他们在系统关闭时输入的内容或使用某些自定义内容一样决定是否“完整”决定是否通过content.data重命名它。

    我不知道你写的是什么类型的数据所以我无法帮助你决定什么是“魔法”,但是如果它是一个xml文件,你可以解析它的正确性,如果你不要得到意外的文件结尾,那么你可能有一个完整的文件。

    FWIW,将自己限制为8k写入并不会省去你,因为你现在依赖于底层操作系统和FS中的实现细节,这些细节可能会在下一个版本中发生变化,或者在以前的版本中会有所不同。

    链接:

    1. http://83.139.107.116:8080/1.1/handlers/monodoc.ashx?link=M%3aMono.Unix.Native.Stdlib.rename(System.String%2cSystem.String