Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/345.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python复制大文件速度太慢_Python_Performance_Copy - Fatal编程技术网

Python复制大文件速度太慢

Python复制大文件速度太慢,python,performance,copy,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分钟以上。有人能解释一下原因并给出一些解决方案吗,最好是使用p

我正在尝试使用
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。目标目录位于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

128.144 s==2.13分钟。即使复制了测试文件,我也有1.7 GB的可用空间。

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

您可以根据以下帖子使用
xcopy
robocopy
来改进这一点:。但在这种情况下,您必须对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)
另见:

  • ,杰夫·阿特伍德关于这个主题的博客文章
  • ,它实际上给出了在Windows上使用xcopy的语法

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

我快速尝试了以下方法:

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
  • 将原始的shutil.py文件复制到示例脚本文件夹,并将其重命名为myshutil.py
  • 将第1行更改为
    import myshutil
  • 编辑了myshutil.py文件,并从
def copyfileobj(fsrc,fdst,长度=16*1024):

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

使用16MB的缓冲区而不是16KB的缓冲区可以极大地提高性能

也许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
这是当前实现的一个简单补丁,在这里可以完美地工作

Python 3.8+:
Python3.8包含了对shutil的一项重大改进,包括将windows缓冲区从16KB增加到1MB(仍然低于本清单中建议的16MB)。你看,

有很多信息,恐怕你的问题的答案是“不”!问题很简单,脚本也很简单,只需将文件从源复制到目标。添加了几行看起来像python脚本的代码。我不明白为什么投了反对票:-(我怀疑部分问题在于Windows已将USB磁盘识别为便携式设备,并对其进行了优化以实现快速删除(以牺牲缓存为代价)例如,请参见Python3.8包含了对shutil的大修/加速。请参见以下链接的答案。我必须通过调用系统命令subprocess.call([“xcopy”,source,target],shell=True)来解决此问题。但是,
shutil.copy()
当然可以。这个答案会起作用,但是,下面的答案提供了问题的解释,不需要特定于系统的代码,而且是pythonic。在web上发现了这个问题:查看他们似乎已经改变了
copyfileobj
以根据操作系统使用
length
值。它现在使用1MB缓冲区(而不是16K)当在Windows上运行时。谢谢。这很有趣!这也适用于函数shutil.copyfile而不是shutil.copy吗?很抱歉,我是一个有能力但又是python新手的程序员,我不太理解你的答案与shutil copy函数的交互作用。我想使用copyfile,这样我就可以将文件重命名为恩,我把它放在新的位置因为python是动态的,解决方案背后的想法是用补丁版本替换原来的函数,定义一个新的默认缓冲区大小。在那里,您将看到,除了“default”参数外,修补的_copyfileobj_几乎是原始的克隆。编辑:您还应该注意,shutil.copyfile使用shutil.copyfileobj。。。