确定客户端计算机Python的下载和上传速度

时间:2014-01-15 20:50:01

标签: python upload download client

我需要使用ftp.retrbinary命令确定FTP期间客户端PC的下载或上传速度。如何确定每个块下载的速度(以Mbps为单位)?

def download_file(block):
    global sizeWritten
    start_time = time.mktime(time.localtime())
    file.write(block)
    end_time = time.mktime(time.localtime())
    os.system('CLS')
    sizeWritten += len(block)
    percentComplete = sizeWritten / totalSize
    percentComplete = round((percentComplete*100),1)

    # if totalTime != 0:
        # throughput=sizeWritten/totalTime
        # throughput=throughput/(1024*1024)
        # throughput=throughput*8
        # throughput=round(throughput,3)
        # print(throughput, "MBPS")
    print (percentComplete, "% complete")

try:
    file = open('100file.zip', "wb")
    print("File opened")
    ftp.retrbinary("RETR " + '100file.zip' ,download_file)
    print("Download Successful!")
except:
    print("Error")

1 个答案:

答案 0 :(得分:0)

您可以通过在转移之前致电(例如datetime.datetime.now())来获取转移开始的时间。

您可以通过在转移后再次呼叫来获取转移结束的时间。

如果你减去这些,你会得到下载的时间。如果您使用的是datetime个对象,则为timedelta

您可以通过例如传输后stat文件获取下载或上传的字节数。

所以:

bytespersec = bytestransfered / (endtime - starttime).totalseconds()

如果你想在传输仍在进行时获得的速度,你不能使用简单的“一次性上传整个文件”命令,但几乎任何FTP库 - 包括stdlib的ftplib - 将具有回调驱动或产量驱动的API,或者提供自己的类文件对象的方法,或者某种其他方式来“挂钩”本地文件的读/写。因此,每次调用钩子时,您可以使用当前时间和到目前为止的总字节数(您可以跟踪)而不是在结束时执行完全相同的计算。

如果你想要那样,你的下一个问题可能是,“如何完成%?”您可以在下载之前询问服务器的文件大小(通过您最喜欢的FTP库的SIZE命令包装器),然后在上传之前stat本地文件,然后每次调用挂钩时,到目前为止,只按总大小划分字节数。 (您可能还想通过执行SIZE并尝试解析两种最典型的格式来为不处理LIST的服务器编写回退代码。或者您的FTP库可能已经有办法这一点。)


根据你的示例代码,你几乎把事情做对了,但是有一个问题:

def download_file(block):
    global sizeWritten
    start_time = time.mktime(time.localtime())
    file.write(block)
    end_time = time.mktime(time.localtime())
    # ...

您只是计算从开始将当前数据块写入磁盘后的时间。如果你想要每个块的时间,从一个块的末尾到下一个块的末尾计数;如果你想要到目前为止的平均时间,从整个过程的开始算起。无论哪种方式,这意味着您需要在调用之间存储start_time的地方。由于您已经在使用sizeWritten的全局变量,因此您可以在此处执行相同操作:

def download_file(block):
    global sizeWritten
    global start_time
    file.write(block)
    end_time = time.mktime(time.localtime())
    # ...

try:
    file = open('100file.zip', "wb")
    sizeWritten = 0
    start_time = time.mktime(time.localtime())

如果你想要时间/阻止,只需在回调函数的末尾添加另一个start_time = time.mktime(time.localtime())。如果您想要两者,只需创建两个变量block_start_timeoverall_start_time,并仅在回调函数结束时重置block_start_time


作为旁注:您永远不会close该文件。这意味着无法保证最后一块数据将被刷新到磁盘。它通常工作(至少在CPython中),但偶尔你会得到截断的文件。永远closeopen的任何内容,特别是在写入模式下,或者更好的是,使用with语句,如the tutorial中所述。

此外,隐藏异常细节会使您的代码难以调试,并且最终用户难以使用。例如,无论您的Internet连接是否已关闭,远程文件是否丢失,或者您没有对本地文件的写入权限,它们都将显示为“错误”。至少打印Exception或其repr,如下所示:

except Exception as e:
    print "Error:", repr(e)