Python:如何快速复制文件

发布于 2021-01-29 15:08:10

这个问题已经在这里有了答案

如何在Python中复制文件?
(17个答案)

5年前关闭。

shutil.copyfile()使用Windows File Explorer或Mac’s
Finder将文件复制到常规右键单击复制>右键单击粘贴的时间至少要长3倍。有没有比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)
关注者
0
被浏览
77
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

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

    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)
    

    此代码的运行速度比本地linux“ cp -rf”慢。

    比较本地存储到tmfps的收益大约是2倍至3倍,而NFS到本地存储则是6倍左右。

    分析后,我注意到shutil.copy做了很多非常重要的fstat
    syscal。如果要进一步优化,我建议对src做一个fstat并重用这些值。老实说,我没有走更远的一步,因为我得到的数字几乎与本地linux复制工具相同,而优化几百毫秒并不是我的目标。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看