如何通过ftp在python中下载大文件(带监控和重新连接)?

时间:2013-10-08 10:53:33

标签: python ftplib

更新#1

问题中的代码非常适合稳定连接(如本地网络或内部网)。

更新#2

我用ftplib实现了FTPClient类,可以:

  1. 监控下载进度
  2. 在超时或断开连接的情况下重新连接
  3. 多次尝试下载文件
  4. 显示当前的下载速度。
  5. 重新连接后,它会从断开点继续下载过程(如果FTP服务器支持它)。有关详细信息,请参阅下面的答案。


    问题

    我必须在python上实现任务,每天通过FTP下载一堆大文件(每个文件0.3-1.5Gb * 200-300个文件)然后对文件进行一些处理。我是通过ftplib做到的。但它不时挂起,无法完成某些文件的下载。为了解决这个问题,我开始使用KEEPALIVE设置,但是我仍然没有收到好的结果

    with closing(ftplib.FTP()) as ftp:
        try:
            ftp.connect(self.host, self.port, 30*60) #30 mins timeout
            # print ftp.getwelcome()
            ftp.login(self.login, self.passwd)
            ftp.set_pasv(True)
            ftp.sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
            ftp.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 75)
            ftp.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 60)
            with open(local_filename, 'w+b') as f:
                res = ftp.retrbinary('RETR %s' % orig_filename, f.write)
    
                if not res.startswith('226 Transfer complete'):
                    logging.error('Downloaded of file {0} is not compile.'.format(orig_filename))
                    os.remove(local_filename)
                    return None
    
            os.rename(local_filename, self.storage + filename + file_ext)
            ftp.rename(orig_filename, orig_filename + '.copied')
    
            return filename + file_ext
    
        except:
                logging.exception('Error during download from FTP')
    

    详情

    • 通常下载文件需要7-15分钟。
    • FTP服务器始终在日志中显示文件已完全下载,但客户端部分挂起。不是每次都是不时。

    问题

    • 可能是因为断开连接?
    • 如何为下载过程实施监视器,并在断开连接时重新连接

1 个答案:

答案 0 :(得分:9)

因为我找不到任何好的建议或代码示例,所以我实现了自己的解决方案。 非常感谢Stackoverflow社区提供了我在代码中使用的一些想法。由于代码的大小(约120行),我将代码放到GitHub(pyFTPclient)。

我在劣质网络上测试了解决方案(包括3G移动互联网),这对我来说还算可行。但当然它可能有一些错误。

我将不胜感激任何意见或建议。 提前谢谢。