この質問は私が持っていた質問から来ました。スタック交換。
私はWindows共有をマウントし、mount -t cifs -o username=username,password=password,rw,nounix,iocharset=utf8,file_mode=0777,dir_mode=0777 //192.168.1.120/storage /mnt/storage
Debianシステムのマウントポイントでスクリプトを実行しました。
マウントポイントには、/mnt/storage
急速に増加するファイルの数が含まれ、このファイルは一括してサブディレクトリに移動され処理されます。
私の問題は、移動が比較的遅いことであり、ファイルテーブル(ファイルがハードドライブ上の情報のみ)だけを変更することはできないために心配です。
私は現在これをPythonで使用していますが、subprocessをshutil.move(src,dst)
使用または使用することも検討しています。os.rename(src,dst)
mv
私の恐怖は正しいですか?それでは、方法がありますか?より効率的に設置?
編集する: 先ほど文書を見直し、shutil.move()
次の内容を読みました。
If the destination is on the current filesystem, then os.rename() is used.
Otherwise, src is copied (using shutil.copy2()) to dst and then removed.
これは問題になりそうですが、そうでない場合「現在のファイルシステムで」、私がそのような人であるかどうかはどうすればわかりますか?「現在のファイルシステムで」
編集2:私が見つけたコンテンツに興味がある人がいる場合は、stackoverflowから編集内容をコピーして貼り付けることもできます。
さまざまな移動方法間の速度差をテストするスクリプトを作成しました。まず 1x5GB( dd if=/dev/urandom of=/mnt/storage/source/test.file bs=100M count=50
) を生成し、次に 100x5MB( for i in {1..100}; do dd if=/dev/urandom of=/mnt/storage/source/file$i bs=1M count=5
)、最後に 10000x5kB( for i in {1..100000}; do dd if=/dev/urandom of=/mnt/storage/source/file$i bs=1k count=5
) を生成します。
from shutil import move
from os import rename
from datetime import datetime
import subprocess
import os
print("Subprocess mv: for every file in directory..")
s = datetime.now()
for f in os.listdir("/mnt/storage/source/"):
try:
subprocess.call(["mv /mnt/storage/source/"+str(f)+" /mnt/storage/mv"],shell=True)
except Exception as e:
print(str(e))
e = datetime.now()
print("took {}".format(e-s)+"\n")
print("Subprocessmv : directory/*..")
s = datetime.now()
try:
subprocess.call(["mv /mnt/storage/mv/* /mnt/storage/mvf"],shell=True)
except Exception as e:
print(str(e))
e = datetime.now()
print("took {}".format(e-s)+"\n")
print("shutil.move: for every file file in directory..")
s = datetime.now()
for f in os.listdir("/mnt/storage/mvf/"):
try:
move("/mnt/storage/mvf/"+str(f),"/mnt/storage/move")
except Exception as e:
print(str(e))
e = datetime.now()
print("took {}".format(e-s)+"\n")
print("os.rename: for every file in directory..")
s = datetime.now()
for f in os.listdir("/mnt/storage/move/"):
try:
rename("/mnt/storage/move/"+str(f),"/mnt/storage/rename/"+str(f))
except Exception as e:
print(str(e))
e = datetime.now()
print("took {}".format(e-s)+"\n")
if os.path.isdir("/mnt/storage/rename_new"):
rmtree('/mnt/storage/rename_new')
print("os.rename & os.mkdir: rename source dir to destination & make new source dir..")
s = datetime.now()
rename("/mnt/storage/rename/","/mnt/storage/rename_new")
os.mkdir("/mnt/storage/rename/")
e = datetime.now()
print("took {}".format(e-s)+"\n")
これは大きな違いがないことを示しています。 5GBファイルは非常に高速に移動しましたが、これはファイルテーブルを変更して移動することが効果的であることを示しています。以下は10000 * 5 kBファイルの結果です(現在のネットワークワークロードによって結果が異なるように感じます。たとえば、最初のmv
テストには2 m 28秒かかり、後で同じファイルを使用して3 m 22秒かかり、os.rename()
ほとんどの場合最速の方法でもあります。):
Subprocess mv: for every file in directory..
took 0:02:47.665174
Subprocessmv : directory/*..
took 0:01:40.087872
shutil.move: for every file file in directory..
took 0:01:48.454184
os.rename: for every file in directory..
rename took 0:02:05.597933
os.rename & os.mkdir: rename source dir to destination & make new source dir..
took 0:00:00.005704