2011-11-30 40 views
5

Tôi đang cố gắng tải xuống tệp sao lưu hàng ngày từ máy chủ của tôi đến máy chủ lưu trữ cục bộ của mình, nhưng tôi đã gặp một số sự cố.Tải xuống các tệp lớn qua FTP với python

tôi đã viết mã này (loại bỏ những phần vô dụng, như chức năng email):

import os 
from time import strftime 
from ftplib import FTP 
import smtplib 
from email.MIMEMultipart import MIMEMultipart 
from email.MIMEBase import MIMEBase 
from email.MIMEText import MIMEText 
from email import Encoders 

day = strftime("%d") 
today = strftime("%d-%m-%Y") 

link = FTP(ftphost) 
link.login(passwd = ftp_pass, user = ftp_user) 
link.cwd(file_path) 
link.retrbinary('RETR ' + file_name, open('/var/backups/backup-%s.tgz' % today, 'wb').write) 
link.delete(file_name) #delete the file from online server 
link.close() 
mail(user_mail, "Download database %s" % today, "Database sucessfully downloaded: %s" % file_name) 
exit() 

Và tôi chạy này với một crontab như:

40 23 * * * python /usr/bin/backup-transfer.py >> /var/log/backup-transfer.log 2>&1 

Nó hoạt động với các tập tin nhỏ, nhưng với các tập tin sao lưu (khoảng 1.7Gb) nó đóng băng, tập tin tải về nhận được khoảng 1.2Gb sau đó không bao giờ lớn lên (tôi chờ đợi một ngày), và các tập tin đăng nhập là sản phẩm nào.

Bất kỳ ý tưởng nào?

p.s: im sử dụng Python 2.6.5

+0

Để khắc phục sự cố tiếp theo, có thể bạn có thể sử dụng đối số 'callback' từ 'FTP.retrbinary' để thu thập thêm thông tin về tiến trình tải xuống. Ngoài ra, chơi với 'maxblocksize' có thể tiết lộ một số vấn đề về mạng. – jcollado

Trả lời

6

Xin lỗi nếu tôi trả lời câu hỏi của riêng mình, nhưng tôi đã tìm ra giải pháp.

Tôi tryed ftputil không thành công, vì vậy tôi tryed nhiều cách và cuối cùng, công trình này:

def ftp_connect(path): 
    link = FTP(host = 'example.com', timeout = 5) #Keep low timeout 
    link.login(passwd = 'ftppass', user = 'ftpuser') 
    debug("%s - Connected to FTP" % strftime("%d-%m-%Y %H.%M")) 
    link.cwd(path) 
    return link 

downloaded = open('/local/path/to/file.tgz', 'wb') 

def debug(txt): 
    print txt 

link = ftp_connect(path) 
file_size = link.size(filename) 

max_attempts = 5 #I dont want death loops. 

while file_size != downloaded.tell(): 
    try: 
     debug("%s while > try, run retrbinary\n" % strftime("%d-%m-%Y %H.%M")) 
     if downloaded.tell() != 0: 
      link.retrbinary('RETR ' + filename, downloaded.write, downloaded.tell()) 
     else: 
      link.retrbinary('RETR ' + filename, downloaded.write) 
    except Exception as myerror: 
     if max_attempts != 0: 
      debug("%s while > except, something going wrong: %s\n \tfile lenght is: %i > %i\n" % 
       (strftime("%d-%m-%Y %H.%M"), myerror, file_size, downloaded.tell()) 
      ) 
      link = ftp_connect(path) 
      max_attempts -= 1 
     else: 
      break 
debug("Done with file, attempt to download m5dsum") 
[...] 

Trong log file của tôi tìm thấy:

01-12-2011 23.30 - Connected to FTP 
01-12-2011 23.30 while > try, run retrbinary 
02-12-2011 00.31 while > except, something going wrong: timed out 
    file lenght is: 1754695793 > 1754695793 
02-12-2011 00.31 - Connected to FTP 
Done with file, attempt to download m5dsum 

Đáng buồn thay, tôi phải kết nối lại với FTP ngay cả khi tập tin đã được tải xuống đầy đủ, rằng trong cas của tôi không phải là một vấn đề, bởi vì tôi phải tải về md5sum quá.

Như bạn thấy, tôi không thể phát hiện thời gian chờ và thử lại kết nối, nhưng khi tôi hết thời gian chờ, tôi chỉ cần kết nối lại; Nếu ai đó biết cách kết nối lại mà không tạo một trường hợp ftplib.FTP mới, hãy cho tôi biết;)

2

Bạn có thể thử đặt thời gian chờ. Từ số docs:

# timeout in seconds 
link = FTP(host=ftp_host, user=ftp_user, passwd=ftp_pass, acct='', timeout=3600) 
2

Tôi đã triển khai mã với ftplib có thể giám sát kết nối, kết nối lại và tải xuống tệp trong trường hợp không thành công. Chi tiết tại đây: How to download big file in python via ftp (with monitoring & reconnect)?

+0

cảm ơn, tôi sẽ cung cấp cho nó một cái nhìn khi tôi tìm thấy một số thời gian miễn phí;) – Strae

+0

@ roman tôi đang sử dụng kịch bản của bạn tôi tải về một kích thước tập tin của 2GB như tôi chạy kịch bản của bạn nó đã bị mắc kẹt khi nó đạt đến kích thước của 'dst_filesize'. – ashim888

Các vấn đề liên quan