Windows上的文本文件的事务处理

时间:2012-12-05 23:56:46

标签: c# windows delphi file-io transactions

我有多个Windows程序(在Windows 2000,XP和7上运行),它们处理不同格式的文本文件(csv,tsv,ini和xml)。在文件IO期间不要破坏这些文件的内容是非常重要的。多个程序应该可以安全地访问每个文件,并且应该能够抵御系统崩溃。 This SO answer建议使用进程内数据库,因此我考虑使用能够Microsoft Jet Database Engine(csv,tsv)和handle delimited text filessupports transactions 。我之前使用过Jet,但我不知道Jet事务是否真的容忍在提交阶段出现意外崩溃或关闭,而且我不知道如何处理非分隔文本文件(ini,xml)。我不认为尝试手动实现完整的ACIDic文件IO是一个好主意。

在Windows上实现文本文件的事务处理的最佳方法是什么?我必须能够在Delphi和C#中执行此操作。

提前感谢您的帮助。

修改

让我们看看基于@ SirRufo的想法的例子。暂时忘掉并发性,让我们专注于容忍碰撞。

  1. 我将文件的内容读入数据结构以修改某些字段。当我在将修改后的数据写回文件的过程中,系统可能会崩溃。

  2. 如果我从不将数据写回原始文件,则可以避免文件损坏。这可以通过创建一个新文件轻松实现,每次保存修改时文件名都带有时间戳。但这还不够:原始文件将保持不变,但新写的文件可能已损坏。

  3. 我可以通过放置" 0"来解决这个问题。时间戳之后的字符,这意味着该文件尚未经过验证。我将通过验证步骤结束写入过程:我将读取新文件,将其内容与我尝试保存的内存结构进行比较,如果它们相同,则将标志更改为&# 34; 1&#34 ;.每次程序必须读取文件时,它会通过比较文件名中的时间戳来选择最新版本。只能保留最新版本,可以删除旧版本。

  4. 可以通过在读取或写入文件之前等待命名的互斥锁来处理并发。当程序获得对文件的访问权限时,它必须从检查文件名列表开始。如果要读取文件,它将读取最新版本。另一方面,只有在没有比上次读取的版本更新的版本时才能开始写作。

  5. 这是一种粗略,过于简单和低效的方法,但它显示了我正在思考的问题。编写文件是不安全的,但也许有一些像上面那样的简单技巧可以帮助避免文件损坏。

    更新

    用Java编写的开源解决方案:

6 个答案:

答案 0 :(得分:5)

如何使用NTFS文件流?将多个命名(编号/时间戳)流写入同一文件名。每个版本都可以存储在不同的流中,但实际上存储在同一个“文件”或一堆文件中,保留数据并提供回滚机制...... 当你达到确定点时删除一些以前的流。

在NT 4中推出?它涵盖了所有版本。应该是防撞证明,你将始终拥有以前的版本/流加上原始版本来恢复/回滚到。

只是一个深夜的想法。

http://msdn.microsoft.com/en-gb/library/windows/desktop/aa364404%28v=vs.85%29.aspx

答案 1 :(得分:4)

您要求的是事务性,如果没有根据您的要求自行开发RDBMS数据库的机制,这是不可能的:

“在文件IO期间不要破坏这些文件的内容非常重要”

选择DBMS。

答案 2 :(得分:1)

查看相关帖子Accessing a single file with multiple threads 但是我的意见是使用像Raven DB这样的数据库进行这类交易,Raven DB支持对同一文件的并发访问,并支持将多个操作的批处理组合到一个请求中。但是,所有内容都保存为JSON文档,而不是文本文件。它确实支持.NET / C#,包括Javascript和HTML,但不支持Delphi。

答案 3 :(得分:1)

首先,这个问题与C#或Delphi无关。您必须模拟文件结构,就好像它是一个数据库一样。

假设;

  • 移动文件是一个便宜的过程,Op System保证文件在移动过程中不会损坏。

  • 您有一个需要处理的文件目录。 (d:\ filesDB * *)

  • 必须使用Controller应用程序。

简化工人流程;

-initialization

  1. 从操作系统获取processID。
  2. 在d:\ filesDB

    中创建目录
    d:\filesDB\<processID>
    d:\filesDB\<processID>\inBox
    d:\filesDB\<processID>\outBox
    
  3. 每个文件的

    -process

    1. 选择要处理的文件。
    2. 将其移至“inBox”目录(确保单次访问文件)
    3. 打开文件
    4. 在“outBox”中创建新文件并正确关闭
    5. 删除“inBox”目录中的文件。
    6. 将位于“OutBox”中的新创建的文件移回d:\ filesDB
    7. -finallization

      1. 删除创建的目录。
      2. 控制器应用

        仅在系统启动时运行,并初始化将执行工作的应用程序。

        1. 扫描子目录的d:\ filesDB目录,
        2. 对于每个子目录 2.1如果文件存在于“inBox”中,则将其移至d:\ filesDB并跳过“outBox”。 2.2如果文件存在于“outBox”中,则将其移至d:\ filesDB 2.3删除整个子目录。
        3. 启动需要启动的每个工作进程。
        4. 我希望这能解决你的问题。

答案 4 :(得分:0)

好的,你死了 - 除非你可以放弃XP。很简单。

由于POST-XP Windows支持Transactional NTFS - 虽然它没有暴露给.NET(本机 - 你仍然可以使用它)。这允许在NTFS文件系统上回滚或提交更改,即使与数据库协调也可以使用DTC。挺棒的。 XP,但是 - 没办法,不存在。

Any real-world, enterprise-grade experience with Transactional NTFS (TxF)?开始作为首发。那里的问题列出了很多资源来帮助你开始学习如何去做。

请注意,此DOES具有性能开销 - 显然。但是,除非你需要一个SECOND事务资源,因为那里有一个非常薄的内核级事务协调器,所以当添加第二个ressource时,事务才会被提升为完整的DTC。

对于直接链接 - http://msdn.microsoft.com/en-us/magazine/cc163388.aspx有一些不错的信息。

答案 5 :(得分:0)

您正在为自己创建一个噩梦,试图处理这些事务,并在您自己的代码中跨多个系统进行说明。这就是为什么Larry Ellison(甲骨文CEO)是亿万富翁,而我们大多数人都不是。如果绝对必须使用文件,则设置支持LOB和CLOB对象的Oracle或其他数据库。我将非常大的SVG文件存储在我公司的这样一个表中,这样我们就可以在没有任何代码更改的情况下向系统添加和渲染大型地图。这些文件可以从表中提取并在缓冲区中传递给用户,然后在完成后返回到数据库。设置适当的安全性和记录锁定,您的问题就解决了。