2017-01-26 51 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倍,這是一個非常可能的緩衝區值。有趣的是,retrbinary的默認緩衝區是8192,它停在的大小是** not ** 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

如果您在cmd中控制檯窗口中運行你的scrpit,嘗試禁用「快速編輯模式」的CMD選項。

我曾經遇到過一個問題,那就是我的ftp腳本在windows下掛起,但在linux中正常工作。最後我發現解決方案正在爲我工​​作。

參考:enter link description here