8

ファイル転送中にタイムアウトすることが多い不安定なFTPサーバーからファイルをダウンロードしていますが、再接続してダウンロードを再開する方法があるかどうか疑問に思っていました。私はPythonのftplibを使用しています。これが私が使用しているコードです:

#! /usr/bin/python

import ftplib
import os
import socket
import sys

#--------------------------------#
# Define parameters for ftp site #
#--------------------------------#
site           = 'a.really.unstable.server'
user           = 'anonymous'
password       = 'someperson@somewhere.edu'
root_ftp_dir   = '/directory1/'
root_local_dir = '/directory2/'

#---------------------------------------------------------------
# Tuple of order numbers to download. Each web request generates 
# an order numbers
#---------------------------------------------------------------
order_num = ('1','2','3','4')

#----------------------------------------------------------------#
# Loop through each order. Connect to server on each loop. There #
# might be a time out for the connection therefore reconnect for #
# every new ordernumber                                          #
#----------------------------------------------------------------#
# First change local directory
os.chdir(root_local_dir)

# Begin loop through 
for order in order_num:
    
    print 'Begin Proccessing order number %s' %order
    
    # Connect to FTP site
    try:
        ftp = ftplib.FTP( host=site, timeout=1200 )
    except (socket.error, socket.gaierror), e:
        print 'ERROR: Unable to reach "%s"' %site
        sys.exit()
    
    # Login
    try:
        ftp.login(user,password)
    except ftplib.error_perm:
        print 'ERROR: Unable to login'
        ftp.quit()
        sys.exit()
     
    # Change remote directory to location of order
    try:
        ftp.cwd(root_ftp_dir+order)
    except ftplib.error_perm:
        print 'Unable to CD to "%s"' %(root_ftp_dir+order)
        sys.exit()

    # Get a list of files
    try:
        filelist = ftp.nlst()
    except ftplib.error_perm:
        print 'Unable to get file list from "%s"' %order
        sys.exit()
    
    #---------------------------------#
    # Loop through files and download #
    #---------------------------------#
    for each_file in filelist:
        
        file_local = open(each_file,'wb')
        
        try:
            ftp.retrbinary('RETR %s' %each_file, file_local.write)
            file_local.close()
        except ftplib.error_perm:
            print 'ERROR: cannot read file "%s"' %each_file
            os.unlink(each_file)
        
    ftp.quit()
    
    print 'Finished Proccessing order number %s' %order
    
sys.exit()

私が得るエラー:

socket.error:[Errno110]接続がタイムアウトしました

どんな助けでも大歓迎です。

4

3 に答える 3

4

標準機能( RFC959を参照)のみを使用してFTP経由でダウンロードを再開するには、コマンドを使用して設定できるブロック送信モード(セクション3.4.2)を使用する必要がありますMODE B。この機能は仕様に準拠するために技術的に必要ですが、すべてのFTPサーバーソフトウェアがこの機能を実装しているかどうかはわかりません。

ブロック送信モードでは、ストリーム送信モードとは対照的に、サーバーはファイルをチャンクで送信します。各チャンクにはマーカーがあります。このマーカーは、失敗した転送を再開するためにサーバーに再送信される場合があります(セクション3.5)。

仕様によると:

[...]システム全体の障害(ホスト、FTPプロセス、または基盤となるネットワークの障害を含む)からユーザーを保護するために、再起動手順が提供されています。

ただし、AFAIKの仕様では、マーカーに必要な寿命は定義されていません。それは次のことだけを言っています:

マーカー情報は送信者にのみ意味がありますが、制御接続のデフォルト言語またはネゴシエートされた言語(ASCIIまたはEBCDIC)の印刷可能な文字で構成されている必要があります。マーカーは、ビットカウント、レコードカウント、またはシステムがデータチェックポイントを識別するためのその他の情報を表すことができます。データの受信者は、再起動手順を実装している場合、受信システム内のこのマーカーの対応する位置をマークし、この情報をユーザーに返します。

この機能を実装するサーバーがFTPセッション間で有効なマーカーを提供すると想定するのは安全ですが、マイレージは異なる場合があります。

于 2011-08-03T22:43:46.670 に答える
1

Python ftplibを使用して再開可能なFTPダウンロードを実装するための簡単な例:

def connect():

ftp = None

with open('bigfile', 'wb') as f:
    while (not finished):
        if ftp is None:
            print("Connecting...")
            FTP(host, user, passwd)

        try:
            rest = f.tell()
            if rest == 0:
                rest = None
                print("Starting new transfer...")
            else:
                print(f"Resuming transfer from {rest}...")
            ftp.retrbinary('RETR bigfile', f.write, rest=rest)
            print("Done")
            finished = True
        except Exception as e:
            ftp = None
            sec = 5
            print(f"Transfer failed: {e}, will retry in {sec} seconds...")
            time.sleep(sec)

よりきめ細かい例外処理をお勧めします。

アップロードの場合も同様です
。Pythonでの切断の処理ftplibFTP転送ファイルのアップロード

于 2021-04-28T07:48:54.943 に答える
-1

これを行うには、中断されたダウンロードを保持し、ファイルのどの部分が欠落しているかを特定し、それらの部分をダウンロードしてから接続する必要があります。これを行う方法はわかりませんが、これを行うDownThemAllと呼ばれるFirefoxおよびChrome用のダウンロードマネージャーがあります。コードはPythonで書かれていませんが(JavaScriptだと思います)、コードを見て、これがどのように行われるかを確認できます。

DownThemll- http://www.downthemall.net/

于 2011-08-03T22:19:40.673 に答える