Esta questão resultou de uma questão minha em stackexchange .
Eu montei um compartilhamento do Windows com 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
e, então, os scripts operam no ponto de montagem em uma máquina debian.
O ponto de montagem /mnt/storage
conterá um número muito rápido de arquivos que são movidos para um subdiretório em lotes, onde são processados.
Meu problema é que a movimentação é relativamente lenta e temo que isso ocorra porque não consigo alterar apenas o filetable (basta alterar as informações onde o arquivo está no disco rígido).
Atualmente, estou usando shutil.move(src,dst)
em python, mas também considero usar os.rename(src,dst)
ou um subprocesso usando mv
.
O meu medo está correto? Em caso afirmativo, há uma maneira de montar de forma mais eficiente ?
edit : Acabei de ler a documentação do shutil.move()
e ler isto:
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.
Isso soa como um problema, se não for "no sistema de arquivos atual" , como sei se estou "no sistema de arquivos atual"
edit2 : Caso alguém esteja interessado no que eu descobri, copio e colo-me edit do stackoverflow aqui também.
Eu escrevi um script para testar as diferenças de velocidade entre os vários métodos de movimentação.
Primeiro criado 1x5GB ( dd if=/dev/urandom of=/mnt/storage/source/test.file bs=100M count=50
), depois com 100x5MB ( for i in {1..100}; do dd if=/dev/urandom of=/mnt/storage/source/file$i bs=1M count=5
) e finalmente com 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")
O que revelou que não há muita diferença. O arquivo de 5GB foi movido muito rápido, o que me diz que o movimento, alterando a tabela de arquivos funciona. Aqui estão os resultados dos arquivos 10000 * 5kB (parecia que os resultados dependem da carga de trabalho atual da rede. Por exemplo, o primeiro mv
test demorou 2m 28s, depois com os mesmos arquivos 3m 22s, também foi os.rename()
o mais rápido método na maioria das vezes ..):
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
Tags performance mount debian cifs move