具有精确连接数的多处理FTP上载

2024-06-07 00:58:44 发布

您现在位置:Python中文网/ 问答频道 /正文

因此,我可以使用多处理功能同时将多个文件上载到给定的服务器上,并具有以下两个功能:

import ftplib,multiprocessing,subprocess

def upload(t):
    server=locker.server,user=locker.user,password=locker.password,service=locker.service #These all just return strings representing the various fields I will need.
    ftp=ftplib.FTP(server)
    ftp.login(user=user,passwd=password,acct="")
    ftp.storbinary("STOR "+t.split('/')[-1], open(t,"rb"))
    ftp.close() # Doesn't seem to be necessary, same thing happens whether I close this or not

def ftp_upload(t=files,server=locker.server,user=locker.user,password=locker.password,service=locker.service):
    parsed_targets=parse_it(t)
    ftp=ftplib.FTP(server)
    ftp.login(user=user,passwd=password,acct="")
    remote_files=ftp.nlst(".")
    ftp.close()
    files_already_on_server=[f for f in t if f.split("/")[-1] in remote_files]
    files_to_upload=[f for f in t if not f in files_already_on_server]
    connections_to_make=3 #The maximum connections allowed the the server is 5, and this error will pop up even if I use 1
    pool=multiprocessing.Pool(processes=connections_to_make)
    pool.map(upload,files_to_upload)

我的问题是,我(非常经常地)最终会犯以下错误:

^{pr2}$

注意:也有一个超时错误,偶尔会发生,但我正在等待它再次抬起它丑陋的头,此时我将发布它。在

当我使用命令行(例如,“ftp-inv”,“open SERVER”,“user USERNAME PASSWORD”,“mput*.rar”)时,我不会遇到这个错误,即使我一次运行了3个这样的实例。在

我已经通读了ftplib和多处理文档,我不知道是什么导致了这些错误。这有点问题,因为我经常备份大量数据和大量文件。在

  1. 有没有什么方法可以避免这些错误,或者有没有另一种方法可以让/a脚本执行此操作?在
  2. 如果这是一个错误的话,我可以告诉它,如果它有一个错误?在
  3. 有没有一种方法可以让脚本以列表中相同的顺序上传文件(当然,速度差异意味着它们不一定总是4个连续的文件,但目前顺序基本上是随机的)?在
  4. 有人能解释一下为什么/怎么会有比脚本所要求的还要多的连接?在

所以,仅仅处理异常似乎是有效的(除了偶尔的递归错误…仍然不知道到底发生了什么)。在

按照#3的说法,我并不是要100%按顺序排列,只是脚本会选择列表中的下一个文件来上载(因此,进程速度的差异可能/仍然会导致顺序不完全是顺序的,与当前系统相比,变化性会小得多,这似乎几乎是无序的)。在


Tags: 文件toin脚本server顺序错误service
2条回答

具体回答(2)有没有办法告诉脚本,如果它有这个错误,它应该等一秒钟,然后继续它的工作?在

是的。在

ftplib.error_temp: 421 Too many connections (5) from this IP

这是个例外。你可以抓住它并处理它。虽然python不支持tail调用,但这是一种糟糕的形式,它可以很简单地如下所示:

^{pr2}$

至于你的问题(3)如果这是你想要的,那就串行上传,而不是并行上传。在

我期待着你张贴更新的答案(4)。我想到的唯一的事情就是用ftp连接到这个IP的其他进程。在

您可以尝试为每个进程使用一个ftp实例:

def init(*credentials):
    global ftp
    server, user, password, acct = credentials
    ftp = ftplib.FTP(server)
    ftp.login(user=user, passwd=password, acct=acct)

def upload(path):
    with open(path, 'rb') as file:
        try:
            ftp.storbinary("STOR " + os.path.basename(path), file)
        except ftplib.error_temp as error: # handle temporary error
            return path, error
        else:
            return path, None

def main():
    # ...
    pool = multiprocessing.Pool(processes=connections_to_make,
                                initializer=init, initargs=credentials)
    for path, error in pool.imap_unordered(upload, files_to_upload):
        if error is not None:
           print("failed to upload %s" % (path,))

相关问题 更多 >