Есть ли специальный трюк для загрузки zip-файла и записи его на диск с помощью Python?

StackOverflow https://stackoverflow.com/questions/576238

  •  05-09-2019
  •  | 
  •  

Вопрос

Я загружаю 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.напишите (фрагмент).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top