You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Paramiko文件传输中计算剩余传输时间?

关于Paramiko文件传输添加剩余时间显示的解决方案

嘿,我来帮你搞定这个问题!首先明确一点:Paramiko本身并没有内置的模块来直接提供传输时间戳或计算剩余传输时间,不过我们可以自己手动实现这个功能,思路其实很清晰。

实现思路

要计算剩余传输时间,我们需要跟踪三个关键数据:

  • 传输开始的时间点
  • 实时的已传输数据量
  • 基于历史传输数据计算的实时传输速度

有了这些数据,就可以用「剩余数据量 ÷ 实时传输速度」得到剩余时间,再把秒数格式化为HH:MM:SS的样式即可。

修改后的完整代码

我基于你现有的代码做了扩展,添加了剩余时间计算的逻辑:

import time
import sys

class YourSFTPClass:
    def __init__(self):
        self.client = None  # 这里替换成你初始化Paramiko SSHClient的代码
        # 新增用于跟踪传输状态的变量
        self.start_time = None
        self.last_sent_bytes = 0
        self.last_update_time = None

    def send_file(self, source, destination):
        # 初始化传输开始时间
        self.start_time = time.time()
        self.last_sent_bytes = 0
        self.last_update_time = self.start_time
        # 启动SFTP传输
        self.client.open_sftp().put(source, destination, self.upload_status)

    def upload_status(self, sent, size):
        # 转换数据单位为MB
        total_mb = round(size / 1000000, 1)
        sent_mb = round(sent / 1000000, 1)
        remaining_mb = round((size - sent) / 1000000, 1)

        # 计算实时传输速度(用最近一次回调的增量,避免初始波动)
        current_time = time.time()
        bytes_delta = sent - self.last_sent_bytes
        time_delta = current_time - self.last_update_time
        
        if time_delta > 0 and bytes_delta > 0:
            # 计算MB/s的速度
            speed_mb_per_sec = (bytes_delta / 1000000) / time_delta
        else:
            # 初始阶段或无数据传输时,速度设为0
            speed_mb_per_sec = 0.0

        # 更新上次记录的状态
        self.last_sent_bytes = sent
        self.last_update_time = current_time

        # 计算剩余时间
        if speed_mb_per_sec > 0:
            remaining_sec = (size - sent) / 1000000 / speed_mb_per_sec
        else:
            remaining_sec = 0  # 或者改为显示"Calculating..."

        # 格式化剩余时间为HH:MM:SS
        hours = int(remaining_sec // 3600)
        minutes = int((remaining_sec % 3600) // 60)
        seconds = int(remaining_sec % 60)
        remaining_time_str = f"{hours:02d}:{minutes:02d}:{seconds:02d}"

        # 输出状态行(覆盖当前行)
        status_output = (
            f"Total size:{total_mb} MB|Sent:{sent_mb} MB|Remaining:{remaining_mb} MB|"
            f"Time remaining:{remaining_time_str}"
        )
        sys.stdout.write(status_output)
        sys.stdout.write('\r')
        sys.stdout.flush()  # 确保输出立即刷新到控制台

关键细节说明

  1. 避免除以0错误:当传输刚开始(还没有数据增量)或者传输暂停时,我们会把速度设为0,此时剩余时间显示为00:00:00,你也可以改成显示Calculating...来提升用户体验。
  2. 实时速度计算:用两次回调之间的字节增量和时间增量计算速度,比用总传输量除以总时间更准确,能反映当前的真实传输速率。
  3. 时间格式化:通过整数运算把剩余秒数转换成小时、分钟、秒,并用02d格式确保两位数的显示(比如1分钟会显示为01)。
  4. 强制刷新输出:添加sys.stdout.flush()确保状态行能实时更新,避免因为缓冲区导致的显示延迟。

内容的提问来源于stack exchange,提问作者Ravish Mallya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:45:32