使用Python处理许多文件

Ste*_*fen 1 python linux sqlite subprocess file

任务:

我正在使用存储在外部USB磁盘上的4 TB数据/文件:图像,html,视频,可执行文件等.

我想使用以下模式索引sqlite3数据库中的所有这些文件:

path TEXT, mimetype TEXT, filetype TEXT, size INT
Run Code Online (Sandbox Code Playgroud)

至今:

我通过挂载目录递归地执行os.walk,file使用python的子进程执行linux 命令,并使用os.path.getsize()获取大小.最后将结果写入数据库,存储在我的计算机上 - 当然,usb安装了-o ro.顺便说一下,没有穿线

你可以在这里看到完整的代码http://hub.darcs.net/ampoffcom/smtid/browse/smtid.py

问题:

代码真的很慢.我意识到,直接结构越深,代码就越慢.我想,os.walk可能是个问题.

问题:

  1. 是否有更快的替代os.walk?
  2. 线程是否会紧固?

aba*_*ert 6

有更快的替代方案os.walk吗?

是.实际上是多重的.

  • scandir(它将在3.5中的stdlib中)明显快于walk.
  • C函数fts明显快于scandir.我很确定PyPI上有包装器,虽然我不知道一个副手推荐,并且它并不难以通过ctypescffi如果你知道任何C.
  • find工具使用fts,subprocess如果您不能fts直接使用,您可以随时使用它.

线程是否会紧固?

这取决于我们没有的系统细节,但是...你花了所有时间等待文件系统.除非你有多个独立的驱动器只在用户级绑定在一起(也就是说,不是LVM或RAID之下的某些东西),或者根本不绑定(例如,一个只是安装在另一个文件系统下),并行发出多个请求可能不会加快速度.

不过,这很容易测试; 为什么不尝试一下呢?


还有一个想法:您可能会花费大量时间来产生并与这些file流程进行通信.有多个Python库使用与libmagic它相同的Python库.我不想特别推荐其中一个,所以这里是搜索结果.


正如monkut建议的那样,确保你正在进行批量提交,而不是使用sqlite自动提交每个插件.正如FAQ所解释的那样,sqlite每秒可以进行大约50000次插入,但每秒只能进行几十次.

在我们处理它的时候,如果你可以将sqlite文件放在与你正在扫描的文件系统不同的文件系统上(或者在你完成之前将它保存在内存中,然后一次性将它写入磁盘),这可能是值得尝试.


最后,但最重要的是:

  • 分析您的代码以查看热点的位置,而不是猜测.
  • 创建小型数据集并对不同的替代方案进行基准测试,以了解您获得的收益