Python 找出FTP上时间A和时间B上的目录列表之间的差异

Python 找出FTP上时间A和时间B上的目录列表之间的差异,python,ftp,ftplib,Python,Ftp,Ftplib,我想建立一个脚本,找出FTP服务器上哪些文件是新的,哪些文件已经被处理。 对于FTP上的每个文件,我们读取信息,对其进行解析,并将所需信息写入数据库。这些文件是xml文件,但必须进行翻译 目前,我正在使用mlsd()获取列表,但这需要4分钟的时间,因为这个目录中已经有15000个文件,每天都会有更多的文件 与其将此列表与保存在文本文件中的旧列表进行比较,我想知道是否有更好的可能性。 由于此任务必须运行“live”,因此每1或2分钟将以cronjob结束。如果这种方法需要很长时间,它将不起作用 解

我想建立一个脚本,找出FTP服务器上哪些文件是新的,哪些文件已经被处理。
对于FTP上的每个文件,我们读取信息,对其进行解析,并将所需信息写入数据库。这些文件是xml文件,但必须进行翻译

目前,我正在使用
mlsd()
获取列表,但这需要4分钟的时间,因为这个目录中已经有15000个文件,每天都会有更多的文件

与其将此列表与保存在文本文件中的旧列表进行比较,我想知道是否有更好的可能性。
由于此任务必须运行“live”,因此每1或2分钟将以cronjob结束。如果这种方法需要很长时间,它将不起作用

解决方案应该是PHP或Python

def handle(self, *args, **options):
    ftp = FTP_TLS(host=host)
    ftp.login(user,passwd)
    ftp.prot_p()
    list = ftp.mlsd("...")
    for item in list:
       print(item[0] + " => " + item[1]['modify'])

此代码示例已经运行了4分钟。

如果FTP是您与服务器的唯一接口,那么没有更好的方法可以完成您正在执行的操作

除非您的服务器支持非标准的
-t
切换到
LIST
/
NLST
命令,该命令返回按时间戳排序的列表。

如果需要很长时间,则下载文件列表(而不是启动下载)。在这种情况下,您可以请求排序列表,但只下载最前面的新文件,一旦找到第一个已处理的文件,就中止列表

有关如何中止文件列表下载的示例,请参阅:

大概是这样的:

class AbortedListing(Exception):
    pass

def collectNewFiles(s):
    if isProcessedFile(s): # your code to detect if the file was processed already
        print("We know this file already: " + s + " - aborting")
        raise AbortedListing()
    print("New file: " + s)

try:
    ftp.retrlines("NLST -t /path", collectNewFiles)
except AbortedListing:
    # read/skip response
    ftp.getmultiline()

我总是尽量避免浏览文件夹来查找可能发生的更改。我更喜欢设置一个专门的工作流程。当只能添加文件(或现有文件的新版本)时,我尝试使用一种工作流,将文件添加到一个目录中,然后转到存档文件的其他目录中。处理可以发生在文件使用后被删除的目录中,也可以发生在文件从一个文件夹复制/移动到另一个文件夹时

作为一个小小的好处,我还使用了复制/重命名模式:首先使用临时名称(例如
.t
前缀或后缀)复制文件,并在复制结束时重命名。这样可以防止尝试处理未完全复制的文件。好的,当我们有慢行时,它过去更重要,但是应该尽可能避免竞争条件,并且它允许使用守护进程,每10秒或更短时间轮询一个文件夹


不确定它在这里是否真的相关,因为它可能需要一些重构,但它提供了防弹解决方案。

不是将一个列表与另一个列表进行比较,我建议保存上次查询的时间戳,并查找自该时间戳之后创建的文件。@J.Ghyllebert,因为您仍然必须使用
mlsd
,因此我认为这并不能解决OP的问题。这是我之前考虑的。最新的想法是运行mlsd->创建列表->压缩backup.zip中已解析的文件并删除单个文件。下次运行mlsd时,它将排除zip,运行时应该更好?@Rune不是每次都创建zip,您还可以将处理过的文件移动到另一个目录。移动是个好主意。压缩不可用,因为您无法在FTP服务器上压缩文件。你必须下载它们,删除远程副本,在本地压缩,然后将压缩文件上传回来(这对我来说没什么意义)虽然这些都不是“在ftp上查找时间A和时间B上的dirlist之间的差异”的答案——如果您正在寻找类似的解决方案,您应该真正更改您的问题标题。如果我的ftp支持此方法,我将尝试。好主意。也许我可以通过在ftp上保存一个文本文件,并带有最后一次检索项目的时间戳来改进它?因此,我只需将排序列表的修改时间与文本文件中的修改时间进行比较,并在其较旧时中止。嗨,我选择了最简单的方法,即使我发现你的方法更好。我现在只是将已解析的文件复制到一个子目录。