2017-01-26 4 views
0

Backstory - это попытка вытащить некоторые данные из входа ftp, который я получил. Эти данные постоянно обновляются, ежедневно, и я считаю, что они уничтожают ftp в конце каждой недели или месяца. Я думал о вводе даты и ежедневном запуске скрипта, чтобы увидеть, есть ли файлы, соответствующие дате, но если время сервера неточно, это может привести к потере данных. Пока я просто хочу загрузить ВСЕ файлы, а затем плохо работать над его тонкой настройкой.ftplib - Python: скрипт зависает при загрузке больших файлов

Я не очень много работал с кодированием ftp, но кажется довольно простым. Тем не менее, проблема, с которой я сталкиваюсь, - это небольшие файлы, которые загружаются без проблем, и их размер файлов проверяется и сопоставляется. Когда он пытается загрузить большой файл, который обычно занимает несколько минут, он достигает определенной точки (почти завершая файл), а затем он просто останавливается и скрипт зависает.

Для примера:

Он пытается загрузить файл, который 373485927 байт. Скрипт запускает и загружает этот файл до 373485568 байт. Он ВСЕГДА останавливается на этой сумме после использования разных методов и изменения кода.

Не понимаю, почему он всегда останавливается в этом байте и почему он будет работать с меньшими файлами (1000 байт и ниже).

import os 
import sys 
import base64 
import ftplib 

def get_files(ftp, filelist): 
    for f in filelist: 
     try: 
      print "Downloading file " + f + "\n" 
      local_file = os.path.join('.', f) 
      file = open(local_file, "wb") 
      ftp.retrbinary('RETR ' + f, file.write) 
     except ftplib.all_errors, e: 
      print str(e) 

     file.close() 
    ftp.quit() 

def list_files(ftp): 
    print "Getting directory listing...\n" 
    ftp.dir() 
    filelist = ftp.nlst() 
    #determine new files to DL, pass to get_files() 
    #for now we will download all each execute 
    get_files(ftp, filelist) 

def get_conn(host,user,passwd): 
    ftp = ftplib.FTP() 
    try: 
     print "\nConnecting to " + host + "...\n" 
     ftp.connect(host, 21) 
    except ftplib.all_errors, e: 
     print str(e) 

    try: 
     print "Logging in...\n" 
     ftp.login(user, base64.b64decode(passwd)) 
    except ftplib.all_errors, e: 
     print str(e) 

    ftp.set_pasv(True) 

    list_files(ftp) 

def main(): 
    host = "host.domain.com" 
    user = "admin" 
    passwd = "base64passwd" 

    get_conn(host,user,passwd) 

if __name__ == '__main__': 
    main() 

Выход выглядит так, как будто файл dddd.tar.gz является большим и никогда не заканчивает его.

Загрузка файла aaaa.del.gz

Загрузка файла bbbb.del.gz

загрузки файлов cccc.del.gz

Выгрузка файла dddd.tar.gz

+0

Звучит как вопрос буферизации. Размер останавливается в кратном 4096, что является очень вероятным значением для буфера. Интересно, что буфер по умолчанию для извлечения - 8192, а размер, на котором он останавливается, равен ** не **, кратное 8192, так что это не тот буфер, который виноват. – spectras

+0

В качестве побочного элемента 'file' является зарезервированным словом в python, вы не должны использовать его как имя переменной. Переименуйте его, например, в 'fd' (для« дескриптора файла »). Я сомневаюсь, что это вызывает здесь проблему, но сначала вы должны устранить эту возможность. – spectras

+0

Кстати, проблема может быть на удаленной стороне, например, FTP-сервер не корректно смывается в конце - какой FTP-сервер вы используете? И вы проверили с другим? – spectras

ответ

0

Это может могут быть вызваны проблемой тайм-аута, возможно, попробуйте:

def get_conn(host,user,passwd): 
    ftp = ftplib.FTP() 

добавить в больших тайм-ауты, пока вы не иметь больше идеи, что происходит, как:

def get_conn(host,user,passwd): 
    ftp = ftplib.FTP(timeout=100) 

Я не уверен, если ftplib по умолчанию тайм-аут или нет, это стоило бы проверять и стоит проверить, если вы время ожидания от сервера. Надеюсь это поможет.

+0

Спасибо, я попробую это. В документации говорится, что он использует глобальный таймаут по умолчанию. Я предполагаю, что это .. >>> import socket >>> print socket.getdefaulttimeout() >>> None – DeNi

+0

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

+0

Это, безусловно, ** не ** проблема с таймаутом. Шанс, что он сломается на идеальном кратном 4096, самый общий размер страницы, действительно низкий. – spectras

0

Если вы используете свой scrpit в окнах CMD консоль, попробуйте отключить "QuickEdit Mode" вариант CMD.

У меня возникла проблема, связанная с тем, что мой ftp-скрипт зависает в окнах, но работает нормально в linux. Наконец я обнаружил, что решение работает для меня.

Ref: enter link description here

Смежные вопросы