使用FTP和列表的Python编程

3 投票
2 回答
962 浏览
提问于 2025-04-17 04:43

我的主要目标是随时检查一个FTP服务器,看看有没有新文件,然后生成一个.txt文件,里面只包含新文件。如果没有新文件,就什么都不返回。现在我已经做了一些工作。我开始时把服务器上的文件复制到oldlist.txt,然后连接到FTP网站,比较newlist.txt和oldlist.txt的数据,把不同的部分放到Temporary FTP file changes.txt里。每次连接时,我都会更新newlist.txt,并把它变成oldlist.txt,这样下次连接时就可以进行比较。请问有没有更好的方法?我的列表每次似乎都没有变化。抱歉如果这让人困惑,谢谢。

import os
filename = "oldlist.txt"
testing = "newlist.txt"
tempfilename = "Temporary FTP file Changes.txt"

old = open(filename, "r")
oldlist = old.readlines()
oldlist.sort()


from ftplib import FTP
ftp = FTP("ftpsite", "username", "password")
ftp.set_pasv(False)
newlist = []
ftp.dir(newlist.append)
newlist.sort()
ftp.close()

bob = open(testing, "w")
for nl in newlist:
    bob.write(nl + "\n")


hello = open(tempfilename, "w")

for c in newlist:
    if c not in oldlist:
    hello.write(c + "\n")

bob.close()
old.close()   
hello.close()

os.remove("oldlist.txt")

os.rename("newlist.txt", "oldlist.txt")

2 个回答

0

你这个方案的实现看起来不错。不过,如果你是想做自动化的FTP消息传递,我可能不会选择这个方案。这个方法有两个缺点:

  • 它不支持重复的文件名。如果一个文件名在“旧”记录中出现过,就不会被识别为新文件。这个问题对你来说可能重要,也可能不重要。但即使现在文件名是唯一的,将来也不一定会一直如此。
  • 它无法告诉你一个新文件是否已经准备好被处理。新文件可能在上传过程中就被处理了。有些人会使用“在X秒内文件大小没有变化”的规则,但这只会增加延迟,并且仍然可能会因为连接中断而出现问题。

有一种类似的方案,没有这两个问题,就是在服务器上用一个保留的文件名存储一个文件,或者放在一个单独的地方,利用它的时间戳(最好是文件本身的修改时间)来判断哪些文件可以安全处理。这个“信号量”文件在上传文件的最后一步时会更新为当前时间。所有修改时间早于信号量时间戳的文件都可以被处理。一旦处理完,所有文件必须从上传文件夹中删除,以免被处理两次。我见过这个方案在自动化生产数据流中运作得很好。

3

把列表转换成集合会简单一些,也快一些,这样就不用担心排序的问题了。

for filename in set(newlist) - set(oldlist):
    print 'New file: ', filename

另外,不用把列表直接保存为文本文件,你可以用shelve模块来创建一个持久化的存储,这样就像使用普通的Python字典一样方便。

除此之外,你的代码简单明了,这很好。

下面是一个详细的例子:

from ftplib import FTP
import shelve

olddir = shelve.open('filelist.shl')   # create a persistent dictionary

ftp = FTP('ftp1.freebsd.org')
ftp.login()

result = []
ftp.dir(result.append)
newdir = set(result[1:])

print ' New Files '.center(50, '=')
for line in sorted(set(newdir) - set(olddir)):
    print line
    olddir[line] = ''
print ' Done '.center(50, '=')
olddir.close()

撰写回答