如何使用Python获得大文件的实时复制进度?
我到处寻找,每次我发现一些看起来有希望的东西都没有淘出来 最后,我想从python内部获取linux机器上文件拷贝的实时进度。我将使用Flask SocketIO将该进程发送到客户端网页,这可能是线程化的,以避免阻塞 我不介意是rsync、copy还是其他任何方式…(shutil等)来处理实际的拷贝。我只需要一个钩子来将更新推到套接字上 到目前为止,我发现这是最有希望的。然而,我并没有完全掌握它的控制台打印机制,因为当我尝试将输出打印到文件时,或者只是一个常规的Python打印,它一次打印一个字符如何使用Python获得大文件的实时复制进度?,python,linux,rsync,flask-socketio,Python,Linux,Rsync,Flask Socketio,我到处寻找,每次我发现一些看起来有希望的东西都没有淘出来 最后,我想从python内部获取linux机器上文件拷贝的实时进度。我将使用Flask SocketIO将该进程发送到客户端网页,这可能是线程化的,以避免阻塞 我不介意是rsync、copy还是其他任何方式…(shutil等)来处理实际的拷贝。我只需要一个钩子来将更新推到套接字上 到目前为止,我发现这是最有希望的。然而,我并没有完全掌握它的控制台打印机制,因为当我尝试将输出打印到文件时,或者只是一个常规的Python打印,它一次打印一个字
import subprocess
import sys
def copy_with_progress(src, dst):
cmd = 'rsync --progress --no-inc-recursive %s %s'%(src, dst)
sub_process = subprocess.Popen(cmd, close_fds=True, shell=True, stdout=subproces.PIPE, stderr=subprocess.PIPE)
while sub_process.poll() is None:
out = sub_process.stdout.read(1)
sys.stdout.write(out)
sys.stdout.flush()
src = '/home/user/Downloads/large_file.tar'
dst = '/media/usbdrive/large_file.tar'
copy_with_progress(src, dst)
从这个问题中可以看出:
但是,这会通过标准输出报告输出。我想在变量中捕获这个输出并发出它
stdout进程如下所示,其中一行不断更新:
大文件.tar
323780608 19%102.99MB/s 0:00:12
当我打印名为'out'的变量时,我会得到一个字符,它会在屏幕上反复循环一行新的字符
如何以可用于传输到客户端的方式捕获此信息
有没有办法在每次刷新状态时获取整行数据?我过去所做的是将数据分块复制,并使用回调函数监控进度。比如:
# Python_2
def copy_with_callback(sourceFile, destinationFile, callbackFunction):
chunk = 4*1024
sourceSize = os.path.getsize(sourceFile)
destSize = 0
with open(sourceFile, 'rb') as fSrc:
with open(destinationFile, 'wb') as fDest:
data = fSrc.read(chunk)
if len(data) == 0:
break
fDest.write(data)
destSize += len(data)
callbackFunction(sourceSize, destSize)
def example_callback_function(srcSize, dstSize):
''' Just an example with print. Your viewer code will vary '''
print 'Do something with these values:', srcSize, dstSize
print 'Percent?', 100.0 * dstSize / srcSize
def main():
src = '/tmp/A/path/to/a/file.txt'
dest = '/tmp/Another/path/to/a/file.txt'
copy_with_callback(src, dest, example_callback_function)
一个优点是python代码不依赖于操作系统特定的功能。只要
stat
源文件以获得总大小,然后定期stat
目标文件以获得当前大小,只要子进程正在运行。您可以查看用户界面的tqdm
包(在手动模式下)。您一次读取一个字节,这就是您希望看到的。您如何读取循环每次迭代的所有可用字节?使用sub_process.stdout.readline()
而不是sub_process.stdout.read会更快一些(1)
好主意!谢谢!