复制shutil.copyfile()
的文件至常规的右键单击副本>至少需要3倍的时间使用Windows文件资源管理器或Mac的Finder右键单击粘贴。
在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)
答案 0 :(得分:13)
最快的版本不会过度优化我使用以下代码获得的代码:
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大约是2x-3x,而NFS到本地存储大约是6x。
在分析之后我注意到shutil.copy做了很多非常重量级的fstat系统。 如果想要进一步优化,我建议为src执行单个fstat并重用这些值。老实说,我没有走得太远,因为我得到了与原生linux复制工具几乎相同的数字,并且优化了几毫秒的毫秒数不是我的目标。
答案 1 :(得分:4)
对于Windows,您只需使用正在执行复制的操作系统:
from subprocess import call
call(["xcopy", "c:\\file.txt", "n:\\folder\\", "/K/O/X"])
/ K - 复制属性。通常,Xcopy会重置只读属性
/ O - 复制文件所有权和ACL信息。
/ X - 复制文件审核设置(隐含/ O)。
答案 2 :(得分:1)
import sys
import subprocess
def copyWithSubprocess(cmd):
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
cmd=None
if sys.platform.startswith("darwin"): cmd=['cp', source, dest]
elif sys.platform.startswith("win"): cmd=['xcopy', source, dest, '/K/O/X']
if cmd: copyWithSubprocess(cmd)
答案 3 :(得分:-1)
这只是一个猜测,但是...... 你的时间错误 ...就是当你复制文件时它打开文件并将其全部读入内存,这样当你粘贴时创建文件并转储内存内容
在python中
copied_file = open("some_file").read()
是 ctrl + c 副本的等效物
然后
with open("new_file","wb") as f:
f.write(copied_file)
是 ctrl + v 粘贴的等效物(所以等于等同的时间......)
如果你希望它可以扩展到更大的数据(但它不会像ctrl + v / ctrl + c那样快
with open(infile,"rb") as fin,open(outfile,"wb") as fout:
fout.writelines(iter(fin.readline,''))