当前位置: 首页 > 面试题库 >

如何快速查找添加/删除的文件?

汪思博
2023-03-14
问题内容

我正在编写一个小程序,该程序创建目录中所有文件的索引。它基本上遍历磁盘上的每个文件,并将其存储到可搜索的数据库中,就像Unix的locate。问题是,由于我有大约一百万个文件,因此索引生成非常慢。

一旦生成索引,是否可以快速找到自上次运行以来已在磁盘上添加或删除了哪些文件?

编辑
:我不想监视文件系统事件。我认为风险太高而无法同步,我更喜欢进行快速重新扫描之类的操作,以快速找到添加/删除文件的位置。也许与目录的上次修改日期有关?

一点基准

我只是做了一个基准。跑步

dir /b /s M:\tests\  >c:\out.txt

只需0.9秒,即可为我提供所需的所有信息。当我使用Java实现(很像这样)时,大约需要4.5秒。有什么想法至少可以改善这种蛮力方法吗?


问题答案:

我已经在工具MetaMake中做到了这一点。这是食谱:

  1. 如果索引为空,则使用时间戳== dir.lastModified()-1将根目录添加到索引。
  2. 在索引中找到所有目录
  3. 将索引中目录的时间戳与文件系统中的时间戳进行比较。由于您具有完整路径(因此不会扫描涉及的树中的所有文件/目录),因此这是一种快速的操作。
  4. 如果时间戳已更改,则此目录已更改。重新扫描并更新索引。
  5. 如果在此步骤中遇到目录丢失的情况,请从索引中删除子树
  6. 如果遇到现有目录,请忽略它(将在步骤2中进行检查)
  7. 如果遇到新目录,请使用timestamp == dir.lastModified()-1添加该目录。确保在步骤2中考虑到它。

这将使您有效地注意到新文件和已删除文件。由于在步骤2中仅扫描已知路径,因此这将非常有效。文件系统很难枚举目录中的所有条目,但是当您知道确切名称时它们很快。

缺点:您不会注意到文件已更改。因此,如果您编辑文件,则 不会
反映在目录更改中。如果您也需要此信息,则必须对索引中的文件节点重复上述算法。这次,您可以忽略新的/已删除的文件,因为它们已经在目录运行期间进行了更新。

[编辑]
Zach提到时间戳是不够的。我的答复是:根本没有其他方法可以做到这一点。对于目录以及从实现到实现的更改,“大小”的概念是完全未定义的。没有API可以在其中注册“我希望在文件系统中发生任何更改时收到通知”。在您的应用程序处于活动状态时,有一些API可以工作,但是如果它停止或错过了一个事件,那么您将失去同步。

如果文件系统是远程的,情况会变得更糟,因为各种网络问题都可能导致您不同步。因此,尽管我的解决方案可能不是100%完美且不漏水,但除了结构最特殊的情况外,它都适用。这是唯一可以做到这一点的解决方案。

现在有一个单一的应用程序,它希望在进行修改后保留目录的时间戳:病毒或蠕虫。这显然会破坏我的算法,但是,这并不是要防止病毒感染。如果要防止这种情况,则必须采用完全不同的方法

实现Zach想要的唯一的另一种方法是建立一个新的文件系统,将该信息永久记录在某个地方,将其出售给Microsoft,然后等待几年(大约10或更多),直到每个人都使用它。



 类似资料:
  • 问题内容: 我有以下查询: 目前,此查询大约需要93分钟才能完成。我想找到使它更快一点的方法。 该表大约有506,000行,其中大约490,000行包含的值,因此我怀疑我是否可以利用此处的任何索引。 该表(未压缩时)中包含约46 gigs的数据,但是该数据的大部分位于名为的文本字段中。我相信简单地加载和卸载许多页面会导致速度下降。一个想法是做一个新表 只是 在和现场,并保持尽可能小。但是,测试该理

  • 我正在尝试: 而不是: 我认为不安全可以比使用常规的数组访问更快地访问内存,并对每个索引进行索引检查... null > 在Oracle java 64位和32位虚拟机上都较慢 无论操作系统和机器体系结构(32位和64位)如何,速度都较慢 即使调用JVM选项也会变慢 Unsafe的速度从9%或更慢(1_GB数组和UnsafeLookup_8B(最快的一个)在32位jvm下面的代码中(64bit甚至

  • 主要内容:UnionFind1.java 文件代码:本小节基于上一小节并查集的结构介绍基础操作,查询和合并和判断是否连接。 查询元素所在的集合编号,直接返回 id 数组值,O(1) 的时间复杂度。 ... private int find ( int p ) {     assert p >= 0 && p < count ;     return id [p ] ; } ... 合并元素 p 和元素 q 所属的集合, 合并过程需要遍历一遍所有元素

  • 问题内容: 由于IE9和Safari-5不支持,因此有什么替代的跨浏览器解决方案? 解决方案 必须 至少在 IE 9 , Safari 5 ,FireFox 4,Opera 11.5和Chrome中运行。 问题答案: 处理没有框架/库的类的一种方法是使用Element.className属性,该属性“ _获取并设置指定元素的class属性的值。 正如在他的回答中已经提到的那样,一旦获得了元素的类字

  • 在上面的示例中,我得到了最近插入的文本,但删除的文本没有显示任何内容(除了println语句中的消息)。 有没有办法从文档中得到最近删除的文本?

  • 问题内容: 我正在尝试将字符串附加到文本文件中。我正在使用以下代码。 这不会将字符串追加到文件。即使我反复调用此函数。 问题答案: 如果您希望能够控制是否追加,请考虑使用。例如: SWIFT 3 顺便说一句,这是一个扩展,可以让你轻松地编写到: 或者,在 Swift 2中 使用: 和