更新平面文件列表的最有效方法

时间:2010-09-15 20:35:46

标签: filesystems

我有一个数据库,其中每个条目都有一个文件路径和一个最后修改过的字段:

1284581625555  C:\docs\text1.txt
1284581646992  C:\docs\text2.txt
1284581654886  C:\docs\text3.txt
1284581662927  C:\docs\subfolder\text4.txt
1284581671986  C:\docs\subfolder\text5.txt
...

每个条目还包含文件内容的摘要,并通过递归地向下走某个文件夹(在本例中为C:\ docs)并添加所有访问过的文件来创建条目。现在我想更新数据库,即

  • 添加新创建的文件
  • 删除已删除的文件
  • 更新已修改的文件

显然,我必须再次沿着根文件夹走,看看有什么变化。但是最有效的方法是什么?

我能想到两种方法:

  • 首先遍历数据库,删除所有已删除的条目并更新所有已修改的条目。为此,每次必须从存储的路径字符串创建文件对象,并调用file.exists()或file.isModified()。然后递归地沿着根文件夹向下走,并添加尚未在数据库中的文件。
  • 首先走下文件树,并在列表中记住添加/删除/修改的内容 - 这需要存储文件树先前状态的完整快照。然后遍历数据库并根据先前创建的列表添加/删除/修改条目。

哪种方法更好?还有其他吗?

编辑:创建摘要非常昂贵(全文提取),遍历数据库也有些昂贵,因为它是基于文件的。

2 个答案:

答案 0 :(得分:2)

我认为最简单的方法是删除并重新创建文件。根据创建“摘要”的难度,这可能是最快的方法,因为您不需要比较或编辑任何内容。

如果摘要创建是“硬”并且数据库适合内存,最简单的方法可能是将数据库加载到dict中(键入文件名,数据指示文件是否已经“看到“)并再次执行os.walk,根据需要更新dict。然后迭代dict,写下所有已经看过的条目。

(顺便说一句,BTW最后修改的字段不一定有用,你必须检查文件的修改时间,所以也可以将它与数据库的时间戳进行比较。)

答案 1 :(得分:1)

处理此问题的最佳方法可能是再次完全重新遍历树。这样,您不是一直调用File.exist(),而是每个目录只调用一次Directory.list()。这可以节省文件IO调用,这很可能是这种情况下的瓶颈。

获得当前存在的文件列表后,您可以比较两个列表,并确定每个文件:

  • 新文件
  • 已删除的文件
  • 更改文件

然后继续进行。