2009-02-23 3 views
1

Я FTP FTP-файл с удаленного FTP-сайта, используя ftplib для Python. Затем я пытаюсь записать его на диск. Файл пишет работает, однако большинство попыток открыть zip с помощью WinZip или WinRar сбой; оба приложения утверждают, что файл поврежден. Как ни странно, при щелчке правой кнопкой мыши и попытке извлечь файл с помощью WinRar, файл будет извлекать.Есть ли специальный трюк для загрузки zip-файла и записи его на диск с помощью Python?

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

Вот код, который я использую, чтобы получить zip-файл с FTP-сайта (пожалуйста, проигнорируйте плохую табуляцию, это не проблема).

filedata = None 
def appender(chunk): 
    global filedata 
    filedata += chunk 


def getfile(filename): 
    try: 
     ftp = None 

     try: 
      ftp = FTP(address) 
      ftp.login('user', 'password') 

     except Exception, e: 
      print e 

     command = 'RETR ' + filename 

     idx = filename.rfind('/') 
     path = filename[0:idx] 
     ftp.cwd(path) 
     fileonly = filename[idx+1:len(filename)] 

     ftp.retrbinary('RETR ' + filename, appender) 

     global filedata 
     data = filedata 

     ftp.close() 

     filedata = '' 
     return data 

    except Exception, e: 
     print e 

data = getfile('/archives/myfile.zip')  
file = open(pathtoNTFileShare, 'wb') 
file.write(data) 
file.close() 

ответ

2

Пасс file.write непосредственно внутри возвратной функции вместо передачи appender. Это будет работать, и при загрузке большого файла он также не будет использовать столько ОЗУ.

Если вы хотите данные, хранящиеся в переменной, хотя, вы можете также имя переменной:

blocks = [] 

Затем переходят к retrbinary вместо Appender:

blocks.append 

Ваш текущий Appender функция неправильная. + = не будет работать правильно, когда есть двоичные данные, потому что он попытается выполнить добавление строки и остановиться в первом NULL, который он видит.

Как уже упоминалось @Lee B, вы также можете использовать urllib2 или Curl. Но ваш текущий код почти прав, если вы сделаете небольшие изменения, упомянутые выше.

1

Я никогда не пользовался этой библиотекой, но urllib2 отлично работает и более прост. Curl еще лучше.

Глядя на ваш код, я вижу пару ошибок. Исключение исключений исключает только исключение, а затем продолжается. Для фатальных ошибок, таких как получение FTP-соединения, им нужно распечатать сообщение, а затем выйти. Кроме того, ваша filedata начинается как None, тогда ваш appender использует + = для добавления к этому, поэтому вы пытаетесь добавить строку + None, которая дает TypeError, когда я пытаюсь ее здесь. Я удивлен, что он работает вообще; Я бы догадался, что приложение добавит исключение, и поэтому копия FTP будет прервана.

При повторном чтении я просто заметил еще один ответ об использовании + = для двоичных данных. Это может быть и так; python иногда пытается быть умным и может «помогать», когда вы присоединяете строки с пробелами или NUL в них или что-то в этом роде. Лучше всего, чтобы файл был открытым (давайте назовем его outfile) и используем ваш appender только для outfile.write (chunk).

+0

Я должен был сказать, что я выбрал все «реальные» обработки исключений, это всего лишь основы, чтобы показать проблему. – ApplePieIsGood