跨多个网络对文件进行原子修改

时间:2009-05-11 15:06:19

标签: c# file atomic

我有一个应用程序正在修改5个相同的xml文件,每个文件位于不同的网络共享上。我知道这是不必要的冗余,但“必须如此。”

每次运行此应用程序时,都会添加/删除/修改一个元素(不多也不少)。

最初,应用程序打开每个xml文件,添加/删除/修改元素到相应的节点并保存文件,如果不能,则抛出错误(无法访问网络共享,超时等...)

我如何制作这种原子?

我最初的假设是:

foreach (var path in NetworkPaths)
    if (!File.Exists(path)
        isAtomic = false;

if (isAtomic)
{
    //Do things
}

但是我可以看到只到目前为止。还有另一种方法可以做到这一点,还是我可以指出的方向?

3 个答案:

答案 0 :(得分:2)

不幸的是,因为真正的“原子”并不是真的可能。我最好的建议就是为此包装你自己的交易形式,这样你至少可以撤消这些变化。

我会检查每个文件 - 如果不存在,请抛出。

备份每个文件,保存撤消所需的状态,或者如果副本不大则将副本保存在内存中。如果你不能,扔掉。

进行编辑,然后保存文件。如果此处出现故障,请尝试从每个备份进行还原。您需要在此处执行一些错误处理,以便在恢复所有备份之前不要抛出。恢复后,抛出异常。

至少这样,您将更有可能不对单个文件进行更改。希望如果您可以修改一个文件,您将能够从备份中恢复/撤消修改。

答案 1 :(得分:1)

我建议采用以下解决方案。

  • 尝试使用写锁定打开所有文件。
    • 如果一个或多个失败,请中止。
    • 修改并刷新所有文件。
      • 如果一个或多个失败,请将已经修改的那些卷回来并重新冲洗它们。
  • 关闭所有文件。

如果回滚失败......那么......再试一次,再试一次,再试一次......然后放弃一个不一致的状态。

如果您可以控制编写此文件的所有进程,则可以使用锁定文件实现简单的锁定机制。您甚至可以执行提前写入日志记录并在锁定文件中记录计划的更改。如果您的进程崩溃,下一个尝试修改文件的人将检测到不完整的操作,并可以在进行一次修改之前继续操作。

答案 2 :(得分:0)

我会介绍文件的版本。您可以通过在文件名后附加后缀来轻松完成此操作。例如计数器变量。读者的过程如下:

  • 准备文件的下一个版本
  • 将其写入具有不同名称的临时文件。
  • 获取最高版本号
  • 将此版本增加一个
  • 将临时文件重命名为新文件
  • 删除旧文件(您可以保留其中2个)

作为读者你做   - 找到具有最高版本的文件   - 读它