Программирование на Python с использованием FTP и списков - PullRequest
3 голосов
/ 21 октября 2011

Моя главная цель - в любое время проверить FTP-сервер на наличие новых файлов, а затем сгенерировать файл .txt, в который скопированы только новые файлы. Если новых файлов нет, то ничего не возвращается. Вот что у меня так далеко. Я начал с копирования файлов с сервера в oldlist.txt, затем подключился к FTP-сайту и сравнил данные из newlist.txt и oldlist.txt, а также различия, которые мне нужны во временном файле FTP 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 ]

3 голосов
/ 21 октября 2011

Немного проще / быстрее конвертировать списки в набор и не беспокоиться о сортировке.

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

Кроме того, вместо сохранения списка в файл в виде необработанного текста, вы можете использовать полкумодуль для создания постоянного хранилища, которое удобно доступно, как обычный Python dict.

В противном случае ваш код обладает простотой и понятностью.

Вот отработанный пример:

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()
0 голосов
/ 21 октября 2011

Ваша реализация этой схемы разумна. Я бы не стал использовать эту схему для реализации автоматического обмена сообщениями по FTP, если вы этим занимаетесь. У этого подхода есть две слабые стороны:

  • Он не поддерживает повторяющиеся имена файлов. Любое имя файла, которое встречается в «старой» истории, не будет обнаружено как новый файл. Может быть, это проблема для вас, а может и нет. Но даже если имена файлов теперь гарантированно уникальны, это не всегда может быть правдой.
  • Он не сообщает вам, готов ли новый файл для использования или нет. Возможно, новый файл будет обработан во время его загрузки. Некоторые люди применяют правило «без изменения размера за X секунд», но это только увеличивает задержку и все еще оставляет уязвимость для разорванных соединений.

Одна схема, которая похожа, но не имеет ни одной из этих двух проблем, заключается в том, чтобы фактически сохранить файл на сервере с зарезервированным именем или в отдельном месте и использовать его метку времени (предпочтительно время модификации самого файла ) решить, какие файлы можно безопасно обработать. Этот файл "семафора" обновляется до текущего времени как последний шаг в загрузке файла. Все файлы с временем модификации старше метки времени семафора могут быть обработаны. После обработки все файлы должны быть удалены из папки загрузки, чтобы они не обрабатывались дважды. Я видел, как эта схема хорошо работает в автоматизированном потоке производственных данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...