Python:如何快速复制文件

alp*_*ric 12 python shutil file-copying

它需要更长的时间至少3次与复制文件shutil.copyfile()与使用Windows资源管理器或Mac的Finder经常右击复制>右键单击粘贴.shutil.copyfile()在Python中有没有更快的替代方案?如何加快文件复制过程?(文件目标位于网络驱动器上......如果它有任何区别......).

稍后编辑:

以下是我最终得到的结果:

def copyWithSubprocess(cmd):        
    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

win=mac=False
if sys.platform.startswith("darwin"):mac=True
elif sys.platform.startswith("win"):win=True

cmd=None
if mac: cmd=['cp', source, dest]
elif win: cmd=['xcopy', source, dest, '/K/O/X']

if cmd: copyWithSubprocess(cmd)
Run Code Online (Sandbox Code Playgroud)

Dmy*_*tro 16

最快的版本没有过度优化我使用以下代码获得的代码:

class CTError(Exception):
    def __init__(self, errors):
        self.errors = errors

try:
    O_BINARY = os.O_BINARY
except:
    O_BINARY = 0
READ_FLAGS = os.O_RDONLY | O_BINARY
WRITE_FLAGS = os.O_WRONLY | os.O_CREAT | os.O_TRUNC | O_BINARY
BUFFER_SIZE = 128*1024

def copyfile(src, dst):
    try:
        fin = os.open(src, READ_FLAGS)
        stat = os.fstat(fin)
        fout = os.open(dst, WRITE_FLAGS, stat.st_mode)
        for x in iter(lambda: os.read(fin, BUFFER_SIZE), ""):
            os.write(fout, x)
    finally:
        try: os.close(fin)
        except: pass
        try: os.close(fout)
        except: pass

def copytree(src, dst, symlinks=False, ignore=[]):
    names = os.listdir(src)

    if not os.path.exists(dst):
        os.makedirs(dst)
    errors = []
    for name in names:
        if name in ignore:
            continue
        srcname = os.path.join(src, name)
        dstname = os.path.join(dst, name)
        try:
            if symlinks and os.path.islink(srcname):
                linkto = os.readlink(srcname)
                os.symlink(linkto, dstname)
            elif os.path.isdir(srcname):
                copytree(srcname, dstname, symlinks, ignore)
            else:
                copyfile(srcname, dstname)
            # XXX What about devices, sockets etc.?
        except (IOError, os.error), why:
            errors.append((srcname, dstname, str(why)))
        except CTError, err:
            errors.extend(err.errors)
    if errors:
        raise CTError(errors)
Run Code Online (Sandbox Code Playgroud)

这段代码比原生linux"cp -rf"慢一点.

比较本地存储的增益到tmfps大约是2x-3x,而NFS到本地存储大约是6x.

在分析之后我注意到shutil.copy做了很多非常重量级的fstat系统.如果想要进一步优化,我建议为src执行单个fstat并重用这些值.老实说,我没有进一步,因为我得到几乎与本机linux复制工具相同的数字,并优化几个毫秒毫秒不是我的目标.

  • 不确定这是否特定于更高版本的python(3.5+),但是`iter`中的sentinel需要为'b''才能停止.(至少在OSX上) (2认同)

Mic*_*rns 5

对于Windows,您可以只使用复制所用的OS:

from subprocess import call
call(["xcopy", "c:\\file.txt", "n:\\folder\\", "/K/O/X"])
Run Code Online (Sandbox Code Playgroud)

/ K-复制属性。通常,Xcopy会重置只读属性
/ O-复制文件所有权和ACL信息。
/ X-复制文件审核设置(表示/ O)。