我用以下代码得到了不过度优化的最快版本:
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)
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" 稍慢一些。
与 shutil 相比,在本地存储到 tmfps 的增益约为 2 倍至 3 倍,而在 NFS 到本地存储的情况下,则约为 6 倍。
在分析过程中,我注意到 shutil.copy 执行了许多相当重量级的 fstat syscals。如果想进一步优化,我建议先对 src 进行单个 fstat 并重用该值。老实说,由于我的目标并不是针对几百毫秒进行优化,所以我没有继续深入研究。
cp
以及Windows的COPY
。它们应该与使用GUI时一样快。 - Ecno92