Python复制较大的文件太慢了

时间:2014-02-15 15:00:08

标签: python performance copy

我正在尝试使用shutil.copy将大文件(> 1 GB)从硬盘复制到USB驱动器。描述我想要做的简单脚本是: -

import shutil
src_file = "source\to\large\file"
dest = "destination\directory"
shutil.copy(src_file, dest)

Linux上只需2-3分钟。但在Windows下,同一文件上的相同文件副本需要10-15分钟。有人可以解释原因并提供一些解决方案,最好使用python代码吗?

更新1

将文件保存为test.pySource文件大小为1 GB。 Destinantion目录位于USB驱动器中。用ptime计算文件复制时间。结果在这里: -

ptime.exe test.py

ptime 1.0 for Win32, Freeware - http://www.
Copyright(C) 2002, Jem Berkes <jberkes@pc-t

===  test.py ===

Execution time: 542.479 s

542.479 s == 9 min。我不认为shutil.copy复制1 GB文件需要9分钟。

更新2

USB的健康状况良好,因为同样的脚本在Linux下运行良好。在Windows native xcopy.Here下使用相同文件计算的时间就是结果。

ptime 1.0 for Win32, Freeware - http://www.pc-tools.net/
Copyright(C) 2002, Jem Berkes <jberkes@pc-tools.net>

===  xcopy F:\test.iso L:\usb\test.iso
1 File(s) copied

Execution time: 128.144 s

128.144 s == 2.13 min。复制测试文件后,我有1.7 GB的可用空间。

2 个答案:

答案 0 :(得分:17)

只是添加一些有趣的信息:WIndows不喜欢shutil实现内部使用的微小缓冲区。

我已经快速尝试了以下内容:

  • 将原始 shutil.py 文件复制到示例脚本文件夹,并将其重命名为 myshutil.py
  • 将第1行更改为import myshutil
  • 编辑了 myshutil.py 文件并更改了 copyfileobj
  

def copyfileobj(fsrc,fdst,length = 16 * 1024):

  

def copyfileobj(fsrc,fdst,length = 16 * 1024 * 1024):

使用16 MB缓冲区而不是16 KB缓冲区可以带来巨大的性能提升。

也许Python需要一些针对Windows内部文件系统特性的调整

修改

在这里找到了更好的解决方案。在文件的开头,添加以下内容:

import shutil

def _copyfileobj_patched(fsrc, fdst, length=16*1024*1024):
    """Patches shutil method to hugely improve copy speed"""
    while 1:
        buf = fsrc.read(length)
        if not buf:
            break
        fdst.write(buf)
shutil.copyfileobj = _copyfileobj_patched

这是当前实施的一个简单补丁,在这里完美运行。

答案 1 :(得分:5)

您的问题与Python无关。事实上,与Linux系统相比,Windows复制过程非常糟糕。

您可以根据以下帖子使用xcopyrobocopy来改善此问题:Is (Ubuntu) Linux file copying algorithm better than Windows 7?。但在这种情况下,你必须对Linux和Windows进行不同的调用......

import os
import shutil
import sys

source = "source\to\large\file"
target = "destination\directory"

if sys.platform == 'win32':
    os.system('xcopy "%s" "%s"' % (source, target))
else:
    shutil.copy(source, target)

另见: