質問

ファイルをコピーするには、少なくとも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)
役に立ちましたか?

解決

次のコードで取得したコードを最適化しすぎない最速のバージョン:

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"よりも少し遅く実行されます。

Shutilと比較すると、tmfpsへのローカルストレージのゲインは約2x-3xであり、NFSからローカルストレージへのゲインは約6xです。

プロファイリングした後、私はそのshutilに気づきました。コピーはかなり重いfstatシステムの多くを行います。さらに最適化したい場合は、srcに対して単一のfstatを実行し、値を再利用することをお勧めします。正直なところ、私はネイティブのlinuxコピーツールとほぼ同じ数字を得て、ミリ秒のいくつかのhundrendsのために最適化することは私の目標ではなかったので、私は

他のヒント

Windowsの場合は、コピーを実行しているOSを使用するだけです:

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

/K-属性をコピーします。通常、Xcopyは読み取り専用属性をリセットします
/O-ファイルの所有権とACL情報をコピーします。
/X-ファイル監査設定をコピーします(/Oを意味します)。

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)

これは単なる推測ですが。.. あなたのタイミングそれは間違っています ...これは、ファイルをコピーするとファイルが開き、すべてメモリに読み込まれるため、貼り付けるとファイルが作成され、メモリの内容がダンプされま

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,''))
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top