Есть ли специальный трюк для загрузки zip-файла и записи его на диск с помощью Python?
Вопрос
Я загружаю zip-файл с удаленного FTP-сайта, используя ftplib на Python.Затем я пытаюсь записать его на диск.Запись в файл работает, однако большинство попыток открыть zip-файл с помощью WinZip или WinRAR завершаются неудачей;оба приложения утверждают, что файл поврежден.Однако, как ни странно, при щелчке правой кнопкой мыши и попытке извлечь файл с помощью WinRAR файл будет извлечь.
Итак, чтобы было ясно, запись в файл будет работать, но не Открыть внутри популярных zip-приложений, но будет распаковывайте с помощью тех же приложений.Обратите внимание, что модуль Python zipfile никогда не удается извлечь молнии.
Вот код, который я использую для получения 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()
Решение
Передайте файл.напишите непосредственно внутри функции retrbinary вместо передачи appender.Это будет работать, и это также не будет использовать так много оперативной памяти, когда вы загружаете большой файл.
Однако, если вы хотите, чтобы данные хранились внутри переменной, вы также можете создать переменную с именем:
blocks = []
Затем перейдите к retrbinary вместо appender:
blocks.append
Ваша текущая функция добавления неверна.+= не будет корректно работать при наличии двоичных данных, потому что он попытается добавить строку и остановится на первом увиденном нулевом значении.
Как упоминал @Lee B, вы также можете использовать urllib2 или Curl.Но ваш текущий код почти корректен, если вы внесете небольшие изменения, о которых я упоминал выше.
Другие советы
Я никогда не пользовался этой библиотекой, но urllib2 работает нормально и является более простым.Curl - это еще лучше.
Глядя на ваш код, я вижу пару неправильных вещей.Ваш перехват исключения только печатает исключение, а затем продолжается.В случае неустранимых ошибок, таких как отсутствие FTP-соединения, им необходимо распечатать сообщение и затем завершить работу.Кроме того, ваши filedata начинаются как None , затем ваше приложение использует += для добавления к этому, поэтому вы пытаетесь добавить строку + None , которая выдает TypeError, когда я пытаюсь это сделать здесь.Я удивлен, что это вообще работает;Я бы предположил, что приложение выдаст исключение, и поэтому FTP-копия будет прервана.
Перечитывая, я только что заметил другой ответ об использовании += для двоичных данных.Это вполне могло быть именно так;python иногда пытается быть умным и может "помочь", когда вы соединяете строки с пробелами или нулями в них, или что-то в этом роде.Ваш лучший выбор - открыть файл (назовем его outfile) и использовать ваше приложение для просто outfile.напишите (фрагмент).