python2.7的paramiko模块下载大文件失败
侧边栏壁纸
  • 累计撰写 5 篇文章
  • 累计收到 12 条评论

python2.7的paramiko模块下载大文件失败

supersu
2024-03-25 / 3 评论 / 78 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2024年03月25日,已超过324天没有更新,若内容或图片失效,请留言反馈。

编程中需要用到 Python(2.7) 的 paramiko 模块下载服务器上面一个比较大的文件,命令如下:

client = paramiko.Transport(ip, port)
client.connect(username=user, password=password)
sftp = paramiko.SFTPClient.from_transport(client)
sftp.get(remotefile, localfile)

发现一个很奇怪的现象,下载比较小的文件时,没有发现异常,直到有一次下载一个 300mb+的文件时,中途卡住一直下载不下来
解决方案:
修改 python 有关 sftp 数据下载的源码,文件位置为:/usr/lib/python2.7/site-packages/paramiko/sftp_file.py
找到_prefetch_thread 函数:

def _prefetch_thread(self, chunks):
    # do these read requests in a temporary thread because there may be
    # a lot of them, so it may block.
    for offset, length in chunks:
        num = self.sftp._async_request(
            self,
            CMD_READ,
            self.handle,
            long(offset),
            int(length))
        with self._prefetch_lock:
            self._prefetch_extents[num] = (offset, length)

代码作者注释说明了此处可能存在并发过大的问题,所以我们对他进行修改:

def _prefetch_thread(self, chunks):
    # do these read requests in a temporary thread because there may be
    # a lot of them, so it may block.
    max_request_num = 512
    to_wait = False
    for offset, length in chunks:
        num = self.sftp._async_request(
            self, CMD_READ, self.handle, long(offset), int(length)
        )
        with self._prefetch_lock:
            self._prefetch_extents[num] = (offset, length)
            if len(self._prefetch_extents) >= max_request_num:
                to_wait = True

        if to_wait:
            time.sleep(1)
            to_wait = False

总体思路就是限制同时存在的异步请求总数

0

评论 (3)

取消
  1. 头像
    ixgqwrcltr
    Windows 10 · Google Chrome

    博主真是太厉害了!!!

    回复
  2. 头像
    qqpvbhvkhb
    Windows 10 · Google Chrome

    真好呢

    回复
  3. 头像
    zbdbqxqvpq
    Windows 10 · Google Chrome

    博主太厉害了!

    回复