1

我正在开发一个涉及维护两个本地目录之间一致性的应用程序。具体来说,目录应该是相同的,除了其中一个目录中的所有文件都以某种特定方式修改(这部分对我的问题不重要)。

在运行时,我的应用程序运行两个进程,它们侦听每个路径下发生的变化,并在必要时执行相关操作以使它们恢复同步。

就我的具体问题而言:我正在寻找有关何时启动应用程序的诡计情况的建议。此时,每个进程都需要检查它所关注的两个路径下的所有文件/文件夹,以查看在应用程序未运行时是否有任何变化。(让我们假设应用程序在关闭时无法被操作系统通知任何发生的事情,因此需要直接检查每个文件/文件夹。)

每个进程都可以访问(并维护)其指定路径下所有文件/文件夹的持久数据结构。我在想每个文件和文件夹的数据结构中应该包含以下内容:

  • 文件/文件夹名称;
  • 文件哈希(CRC32);
  • 文件/文件夹最后一个 mod 数据;和
  • 文件/文件夹大小。

这些信息显然有助于检查文件/文件夹的任何更改,但是存储它们的最佳方式是什么?

在我看来,处理应用程序启动情况的一种明智方法是让每个进程递归扫描其指定路径下的所有文件/文件夹,并将扫描到的每个文件的元数据与其数据结构中存储的元数据进行比较. 然后流程还应该遍历数据结构以查找已从路径中删除的内容。在此过程中可能会遇到的一些情况是:

  • 文件已修改(在数据结构中找到文件名,但哈希值不同);
  • 添加的文件(在数据结构中找不到相同的文件名或哈希);
  • 文件重命名(具有相同哈希的文件存在于数据结构中,但文件名不同);
  • 添加的文件夹(数据结构中没有文件夹名称);
  • 删除文件夹(数据结构中的文件夹名称,但不在路径下);
  • 文件夹重命名(棘手的一个)。

那么,用于此任务的最佳数据结构是什么?在我的脑海中,我正在考虑某种形式的排序关联数组,例如,一棵红黑树,它存储filefolder对象。每个file对象都包含和属性name,而每个对象都包含和属性,其中存储了另一个关联数组,其中包含下面的所有内容。给定任意文件的路径,例如 ,您从根 ( ) 开始,检查等等,直到您到达的父对象。hashmod-datefoldernamechildrenchildren/foo/bar/file.txtfoobarfile.txt

我能想到的另一种选择是仅将所有内容平坦地存储,这样就有一个红黑树,其中每个键是每个文件/文件夹的完整路径,值是file/folder对象。这可能会更快地进行检索,但是如果不遍历所有值就不可能检测到重命名的文件/文件夹,这听起来很昂贵。在第一种方法中,识别重命名可能只涉及检查数据结构的一部分而不是全部。

抱歉,上述想法并没有经过深思熟虑。该领域的最新技术是什么,对于这些类型的问题是否有任何成熟的方法?

4

1 回答 1

0

您正在对文件系统进行建模,因此使用分层数据结构是很自然的。毕竟,您不需要将 dir1\dir2\foo.txt 处的文件与 dir3\bar.txt 进行比较,对吧?您没有提到目录之间的文件移动是您正在跟踪的内容。

所以,数据结构可以是:

interface IFSEntry {
  string name
  datetime creationDate
  pure virtual bool Compare(IFSEntry other)
  pure virtual void UpdateFrom(IFSEntry other)
  pure virtual bool WasRenamed(Dictionary<string,IFSEntry> possibleOriginals, out string oldName)
  ...
} 

class File : IFSEntry {
  ...
} 

class Directory : IFSEntry {
  private Dictionary<string,IFSEntry> children;
  ...
}

UpdateFrom 和 Compare 的 Directory 实现将递归它们的子级。

通过比较 CRC,文件重命名会相对容易。你会错过在这两个地方都发生了变化并被重命名的文件。如果运行比较的时间证明存在性能问题,您可以将 CRC 字典添加到 Directory 类。

对于目录移动,如果子文件也发生了变化,那么你就有了一个模糊的逻辑情况。最好有一个用户可以针对这种情况操作的合并工具。

如果一个文件在两个地方都发生了更改,那么如果发生冲突更改,您还需要一个面向用户的合并策略。我认为这始终是一个好主意,只是为了让用户注意到文档没有失去连贯性。

于 2011-06-30T21:55:50.593 回答