shutil.copyfile()使用Windows File Explorer或Mac’s Finder将文件复制到常规右键单击复制>右键单击粘贴的时间至少要长3倍。有没有比shutil.copyfile()Python更快的替代方法?可以采取什么措施来加快文件复制过程?(文件目标位于网络驱动器上……如果有任何区别……)。
shutil.copyfile()
这是我最终得到的结果:
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)
最快的版本,没有使用以下代码过度优化我的代码:
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复制工具相同,而优化几百毫秒并不是我的目标。