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

Find out differences between directory listings on time A and time B on FTP

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

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

我不想将此列表与我保存在文本文件中的旧列表进行比较,而是想知道是否有更好的可能性。
因为这个任务必须 运行 "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'])

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

如果 FTP 是您与服务器的唯一接口,那么没有比您已经在做的更好的方法了。

除非你的服务器支持非标准 -t 切换到 LIST/NLST 命令,returns 列表按时间戳排序。
参见

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

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

像这样:

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()

我一直试图避免通过浏览文件夹来查找可能已更改的内容。我更喜欢设置专门的工作流程。当只能添加文件(或现有文件的新版本)时,我尝试使用一种工作流程,其中将文件添加到一个目录中,然后转到其他目录中进行归档。处理可能发生在文件在使用后被删除的目录中,或者当它们 copied/moved 从一个文件夹到另一个文件夹时。

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

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