0

晚上好。我正在考虑开发一些代码,这些代码将从 JPEG 图像中收集 EXIF 数据并使用 Python v2.x 将其存储在 MySQL 数据库中。绊脚石在于 JPEG 分散在多个子目录和根目录中的更多子目录中例如 200 个 JPEG 可以存储在 root > subroot > subsubroot1 中,另外 100 个 JPEG 可以存储在 root > subroot > subroot2 中。一旦识别出所有图像,它们将被扫描并在添加到 MySQL 表之前提取它们各自的 EXIF 数据。

目前我正处于计划阶段,但我只是想知道,执行递归搜索的最有效和最pythonic的方法是什么?我正在寻找扫描根目录并将任何新识别的子目录附加到列表中,然后扫描列表中的所有子目录路径以查找更多子目录,直到我拥有所有目录的总列表。尽管恕我直言,这似乎是一种笨拙的方式并且有点重复,所以我认为可能有一种更面向对象的方式来执行此功能。

同样,我只想将新信息添加到我的 MySQL 表中,那么确定条目是否已经存在的最有效方法是什么?表中的文件名和 JPEG 文件名都将是其 MD5 哈希值。我正在考虑扫描代码开头的表格并将所有文件名放在一个集合中,因此,在扫描新的 JPEG 之前,如果集合中已经存在一个条目,则无需提取 EXIF 并继续下一张照片。然而,这是一种有效的方法,还是在遇到新图像时扫描 MySQL 表会更好?我预计 set 方法可能是最有效的,但是该表最终可能包含数千万个条目,因此将这些条目的文件名添加到集合(易失性内存)中可能不是最好的主意。

谢谢各位。

4

1 回答 1

2

我只想编写一个扫描目录中所有文件的函数;如果是 jpeg,请将 jpeg 的完整路径名添加到结果列表中。如果是目录,则立即以新发现的目录作为参数调用该函数。如果它是另一种类型的文件,则什么也不做。这是一个经典的递归分治策略。如果您的目录路径中有循环,例如符号链接,它将中断 - 如果这对您来说是危险的,那么您必须确保您不会通过查找“真实”非遍历同一个目录两次- 每个目录的符号链接路径并记录它。

如何避免重复条目是一个棘手的问题,您必须考虑是否可以容忍两个具有完全相同内容的不同名称的文件(并且还要考虑符号链接或多重硬链接文件的边缘情况),新文件如何出现在您正在扫描的目录中,以及您是否可以控制该过程。加快速度的一种方法是使用os.path.getmtime(). 记录您开始目录遍历过程的那一刻。下一次,让您的递归遍历过程忽略任何 mtime 早于您记录的时间的 jpeg 文件。这不能是您跟踪的唯一方法,因为在您的流程的开始和结束时间之间修改的文件可能会或可能不会被记录,因此您仍然需要检查数据库中的这些记录(例如使用完整路径,文件信息的哈希值或数据本身的哈希值,具体取决于您不能容忍的重复类型),但用作启发式方法应该可以大大加快处理速度。

理论上,您可以将数据库中的所有文件名(可能是路径而不是文件名)加载到内存中以加快比较速度,但如果表存在变得非常大的任何危险,最好将该信息留在数据库中。例如,您可以从文件名创建一个哈希,然后简单地将其添加到具有 UNIQUE 约束的数据库中——数据库将拒绝任何重复的条目,您可以捕获异常并继续执行。如果您使用上述启发式检查文件 mtime,这不会很慢。

如果这对您的应用程序很重要,请确保您考虑到文件可能只被修改而不是新创建的可能性。

于 2012-05-05T18:09:56.580 回答