Risposte:
shutil
ha molti metodi che puoi usare. Uno dei quali è:
from shutil import copyfile
copyfile(src, dst)
Se si utilizzano le os.path
operazioni, utilizzare copy
anziché copyfile
. copyfile
si accettano solo le stringhe .
~
, ma può gestire percorsi relativi
┌──────────────────┬────────┬───────────┬───────┬────────────────┐
│ Function │ Copies │ Copies │Can use│ Destination │
│ │metadata│permissions│buffer │may be directory│
├──────────────────┼────────┼───────────┼───────┼────────────────┤
│shutil.copy │ No │ Yes │ No │ Yes │
│shutil.copyfile │ No │ No │ No │ No │
│shutil.copy2 │ Yes │ Yes │ No │ Yes │
│shutil.copyfileobj│ No │ No │ Yes │ No │
└──────────────────┴────────┴───────────┴───────┴────────────────┘
copy2(src,dst)
è spesso più utile di copyfile(src,dst)
perché:
dst
di essere una directory (anziché il nome file di destinazione completo), nel qual caso il nome base di src
viene utilizzato per creare il nuovo file;Ecco un breve esempio:
import shutil
shutil.copy2('/src/dir/file.ext', '/dst/dir/newname.ext') # complete target filename given
shutil.copy2('/src/file.ext', '/dst/dir') # target filename is /dst/dir/file.ext
copyfile
è considerevolmente più veloce dicopy2
shutil.copy2('/dir/file.ext', '/new/dir/')
(con la barra dopo il percorso target) rimuoverà l'ambiguità rispetto alla copia in un nuovo file chiamato "dir" o se il file viene inserito in una directory con quel nome?
/new/dir
esiste una directory esistente, vedere il commento di @ MatthewAlpert.
/new/dir/
non esiste, Python lancerà un IsADirectoryError
, altrimenti copia il file /new/dir/
con il nome originale.
È possibile utilizzare una delle funzioni di copia da shutil
pacchetto:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━ La funzione conserva i supporti accetta altre copie directory delle autorizzazioni dest. file obj metadata -------------------------------------------------- ---------------------------- shutil.copy ✔ ✔ ☐ ☐ shutil.copy2 ✔ ✔ ☐ ✔ shutil.copyfile ☐ ☐ ☐ ☐ shutil.copyfileobj ☐ ☐ ✔ ☐ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Esempio:
import shutil
shutil.copy('/etc/hostname', '/var/tmp/testhostname')
In Python, puoi copiare i file usando
shutil
moduloos
modulosubprocess
moduloimport os
import shutil
import subprocess
shutil
moduloshutil.copyfile
firma
shutil.copyfile(src_file, dest_file, *, follow_symlinks=True)
# example
shutil.copyfile('source.txt', 'destination.txt')
shutil.copy
firma
shutil.copy(src_file, dest_file, *, follow_symlinks=True)
# example
shutil.copy('source.txt', 'destination.txt')
shutil.copy2
firma
shutil.copy2(src_file, dest_file, *, follow_symlinks=True)
# example
shutil.copy2('source.txt', 'destination.txt')
shutil.copyfileobj
firma
shutil.copyfileobj(src_file_object, dest_file_object[, length])
# example
file_src = 'source.txt'
f_src = open(file_src, 'rb')
file_dest = 'destination.txt'
f_dest = open(file_dest, 'wb')
shutil.copyfileobj(f_src, f_dest)
os
moduloos.popen
firma
os.popen(cmd[, mode[, bufsize]])
# example
# In Unix/Linux
os.popen('cp source.txt destination.txt')
# In Windows
os.popen('copy source.txt destination.txt')
os.system
firma
os.system(command)
# In Linux/Unix
os.system('cp source.txt destination.txt')
# In Windows
os.system('copy source.txt destination.txt')
subprocess
modulosubprocess.call
firma
subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False)
# example (WARNING: setting `shell=True` might be a security-risk)
# In Linux/Unix
status = subprocess.call('cp source.txt destination.txt', shell=True)
# In Windows
status = subprocess.call('copy source.txt destination.txt', shell=True)
subprocess.check_output
firma
subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, universal_newlines=False)
# example (WARNING: setting `shell=True` might be a security-risk)
# In Linux/Unix
status = subprocess.check_output('cp source.txt destination.txt', shell=True)
# In Windows
status = subprocess.check_output('copy source.txt destination.txt', shell=True)
['copy', sourcefile, destfile]
sintassi laddove possibile, specialmente se i parametri provengono dall'input dell'utente.
os.popen
è obsoleto da un po 'di tempo. e check_output
non restituisce lo stato ma l'output (che è vuoto nel caso di copy/cp
)
La copia di un file è un'operazione relativamente semplice, come mostrato negli esempi seguenti, ma per questo è necessario utilizzare il modulo shutil stdlib .
def copyfileobj_example(source, dest, buffer_size=1024*1024):
"""
Copy a file from source to dest. source and dest
must be file-like objects, i.e. any object with a read or
write method, like for example StringIO.
"""
while True:
copy_buffer = source.read(buffer_size)
if not copy_buffer:
break
dest.write(copy_buffer)
Se vuoi copiare per nome file puoi fare qualcosa del genere:
def copyfile_example(source, dest):
# Beware, this example does not handle any edge cases!
with open(source, 'rb') as src, open(dest, 'wb') as dst:
copyfileobj_example(src, dst)
shutil.copyfileobj
. Inoltre, non è try, finally
necessario gestire la chiusura dei file dopo le eccezioni. Direi tuttavia che la tua funzione non dovrebbe essere responsabile dell'apertura e della chiusura dei file. Dovrebbe andare in una funzione wrapper, come il shutil.copyfile
wrapping shutil.copyfileobj
.
dest
di essere scrivibile:open(dest, 'wb')
Utilizzare il modulo shutil .
copyfile(src, dst)
Copia il contenuto del file denominato src in un file chiamato dst. La posizione di destinazione deve essere scrivibile; in caso contrario, verrà sollevata un'eccezione IOError. Se dst esiste già, verrà sostituito. File speciali come dispositivi a caratteri o blocchi e pipe non possono essere copiati con questa funzione. src e dst sono nomi di percorso dati come stringhe.
Dai un'occhiata a filesys per tutte le funzioni di gestione di file e directory disponibili nei moduli Python standard.
Esempio di copia di directory e file - Da Tim Golden's Python Stuff:
http://timgolden.me.uk/python/win32_how_do_i/copy-a-file.html
import os
import shutil
import tempfile
filename1 = tempfile.mktemp (".txt")
open (filename1, "w").close ()
filename2 = filename1 + ".copy"
print filename1, "=>", filename2
shutil.copy (filename1, filename2)
if os.path.isfile (filename2): print "Success"
dirname1 = tempfile.mktemp (".dir")
os.mkdir (dirname1)
dirname2 = dirname1 + ".copy"
print dirname1, "=>", dirname2
shutil.copytree (dirname1, dirname2)
if os.path.isdir (dirname2): print "Success"
In primo luogo, ho creato un completo cheat sheet dei metodi di shutil come riferimento.
shutil_methods =
{'copy':['shutil.copyfileobj',
'shutil.copyfile',
'shutil.copymode',
'shutil.copystat',
'shutil.copy',
'shutil.copy2',
'shutil.copytree',],
'move':['shutil.rmtree',
'shutil.move',],
'exception': ['exception shutil.SameFileError',
'exception shutil.Error'],
'others':['shutil.disk_usage',
'shutil.chown',
'shutil.which',
'shutil.ignore_patterns',]
}
In secondo luogo, spiegare i metodi di copia negli esempi:
shutil.copyfileobj(fsrc, fdst[, length])
manipolare oggetti aperti
In [3]: src = '~/Documents/Head+First+SQL.pdf'
In [4]: dst = '~/desktop'
In [5]: shutil.copyfileobj(src, dst)
AttributeError: 'str' object has no attribute 'read'
#copy the file object
In [7]: with open(src, 'rb') as f1,open(os.path.join(dst,'test.pdf'), 'wb') as f2:
...: shutil.copyfileobj(f1, f2)
In [8]: os.stat(os.path.join(dst,'test.pdf'))
Out[8]: os.stat_result(st_mode=33188, st_ino=8598319475, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=20, st_size=13507926, st_atime=1516067347, st_mtime=1516067335, st_ctime=1516067345)
shutil.copyfile(src, dst, *, follow_symlinks=True)
Copia e rinomina
In [9]: shutil.copyfile(src, dst)
IsADirectoryError: [Errno 21] Is a directory: ~/desktop'
#so dst should be a filename instead of a directory name
shutil.copy()
Copia senza conservare i metadati
In [10]: shutil.copy(src, dst)
Out[10]: ~/desktop/Head+First+SQL.pdf'
#check their metadata
In [25]: os.stat(src)
Out[25]: os.stat_result(st_mode=33188, st_ino=597749, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=20, st_size=13507926, st_atime=1516066425, st_mtime=1493698739, st_ctime=1514871215)
In [26]: os.stat(os.path.join(dst, 'Head+First+SQL.pdf'))
Out[26]: os.stat_result(st_mode=33188, st_ino=8598313736, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=20, st_size=13507926, st_atime=1516066427, st_mtime=1516066425, st_ctime=1516066425)
# st_atime,st_mtime,st_ctime changed
shutil.copy2()
Copia con la conservazione dei metadati
In [30]: shutil.copy2(src, dst)
Out[30]: ~/desktop/Head+First+SQL.pdf'
In [31]: os.stat(src)
Out[31]: os.stat_result(st_mode=33188, st_ino=597749, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=20, st_size=13507926, st_atime=1516067055, st_mtime=1493698739, st_ctime=1514871215)
In [32]: os.stat(os.path.join(dst, 'Head+First+SQL.pdf'))
Out[32]: os.stat_result(st_mode=33188, st_ino=8598313736, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=20, st_size=13507926, st_atime=1516067063, st_mtime=1493698739, st_ctime=1516067055)
# Preseved st_mtime
shutil.copytree()
Copia ricorsivamente un intero albero di directory radicato su src, restituendo la directory di destinazione
Per file di piccole dimensioni e utilizzando solo i built-in python, è possibile utilizzare il seguente one-liner:
with open(source, 'rb') as src, open(dest, 'wb') as dst: dst.write(src.read())
Come @maxschlepzig ha menzionato nei commenti seguenti, questo non è un modo ottimale per le applicazioni in cui il file è troppo grande o quando la memoria è critica, quindi la risposta di Swati dovrebbe essere preferita.
.read()
e .write()
sono bufferizzati di default (almeno per CPython).
open()
IO bufferizzato, per impostazione predefinita non ti aiuta qui, perché read()
è specificato come: 'Se n è negativo o omesso, leggi fino a EOF.' Ciò significa che read()
restituisce il contenuto completo del file come stringa.
Puoi usare os.system('cp nameoffilegeneratedbyprogram /otherdirectory/')
o come l'ho fatto,
os.system('cp '+ rawfile + ' rawdata.dat')
dov'è rawfile
il nome che avevo generato all'interno del programma.
Questa è una soluzione solo per Linux
shutil
non è disponibile - subprocess.run()
(senza shell=True
!) È la migliore alternativa a os.system()
.
subprocess.run()
come suggerito da @maxschlepzig è un grande passo avanti quando si chiamano programmi esterni. Per flessibilità e sicurezza, tuttavia, utilizzare il ['cp', rawfile, 'rawdata.dat']
modulo per passare la riga di comando. (Tuttavia, per la copia, shutil
si consiglia agli amici di chiamare un programma esterno.)
Per file di grandi dimensioni, ciò che ho fatto è stato leggere il file riga per riga e leggere ogni riga in un array. Quindi, una volta che l'array ha raggiunto una determinata dimensione, aggiungerlo a un nuovo file.
for line in open("file.txt", "r"):
list.append(line)
if len(list) == 1000000:
output.writelines(list)
del list[:]
for l in open('file.txt','r'): output.write(l)
dovrebbe funzionare trovare; basta impostare il buffer del flusso di output in base alle proprie esigenze. oppure puoi passare dai byte ripetendo ciclicamente un tentativo con output.write(read(n)); output.flush()
dov'è n
il numero di byte che desideri scrivere alla volta. entrambi questi non hanno anche una condizione per verificare quale sia un bonus.
shutil
? Anche quando si ignora shutil
, un semplice ciclo di lettura / scrittura a blocchi (usando IO non bufferizzato) è semplice, sarebbe efficiente e avrebbe molto più senso di così, e quindi è sicuramente più facile da insegnare e capire.
from subprocess import call
call("cp -p <file> <file>", shell=True)
call
non è sicuro. Si prega di fare riferimento al documento sui sottoprocessi al riguardo.
A partire da Python 3.5 è possibile effettuare le seguenti operazioni per file di piccole dimensioni (ad esempio: file di testo, jpeg di piccole dimensioni):
from pathlib import Path
source = Path('../path/to/my/file.txt')
destination = Path('../path/where/i/want/to/store/it.txt')
destination.write_bytes(source.read_bytes())
write_bytes
sovrascriverà qualunque cosa fosse nella posizione di destinazione
shutil
gestisce tutti i casi speciali per te e ti dà tranquillità.
open(destination, 'wb').write(open(source, 'rb').read())
Apri il file sorgente in modalità lettura e scrivi sul file di destinazione in modalità scrittura.
.close()
su tutti quei open(...)
s?
Python offre funzioni integrate per copiare facilmente i file utilizzando le utility Shell del sistema operativo.
Il seguente comando viene utilizzato per copiare il file
shutil.copy(src,dst)
Il comando seguente viene utilizzato per copiare il file con le informazioni MetaData
shutil.copystat(src,dst)
copy
quindi eseguirlo copystat
per conservare i metadati del file. In Python 3.3+ copystat
copia anche gli attributi estesi.