2012-05-05 45 views
0

晚上好。我正在研究一些代码,它们将从JPEG图像中收集EXIF数据并使用Python v2.x将其存储在MySQL数据库中。绊脚石在于,JPEG分散在许多子目录和更多子目录中所以例如200个JPEG可能存储在root> subroot> subsubroot1中,另外100个存储在root> subroot> subroot2中。一旦所有图像被识别出来,它们将被扫描,并且它们各自的EXIF数据在被添加到MySQL表之前被抽象化。递归搜索和MySql比较

目前我只是在计划阶段,但我只是想知道,执行递归搜索最有效和最蟒蛇的方法是什么?我正在查找扫描根目录并将任何新识别的子目录附加到列表中,然后扫描列表中的所有子目录路径以获取更多子目录,直到获得所有目录的全部列表。这似乎是一个笨拙的方式,虽然恕我直言,有点重复,所以我认为可能有更多的OOP方式来执行此功能。

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

谢谢大家。

回答

2

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

如何避免重复输入是一个棘手的问题,您必须考虑您是否容忍两个具有完全相同内容的不同名称的文件(并考虑符号链接或多重 - 硬链接文件的边缘情况) ,您正在扫描的目录中新文件的显示方式,以及您是否对该过程有任何控制权。加速它的一个想法是使用os.path.getmtime()。记录你开始目录遍历过程的时刻。下一次,你的递归遍历过程会忽略任何比你的记录时间早mtime的jpeg文件。这不是您唯一的跟踪方法,因为在您的流程的开始和结束时间之间修改的文件可能会或可能不会被记录,所以您仍然必须检查数据库中的这些记录(例如使用完整路径,对文件信息的散列或对数据本身的散列,取决于你不能容忍的重复类型),但是用作启发式应用程序会极大地加速该过程。

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

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