Odpowiedzi:
shutilma wiele metod, których możesz użyć. Jednym z nich jest:
from shutil import copyfile
copyfile(src, dst)
Jeśli korzystasz z os.pathoperacji, użyj copyraczej niż copyfile. copyfilebędzie akceptować tylko ciągi .
~, ale może radzić sobie ze ścieżkami względnymi
┌──────────────────┬────────┬───────────┬───────┬────────────────┐
│ 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)jest często bardziej przydatny niż copyfile(src,dst)dlatego, że:
dstsię do katalogu (zamiast pełnej nazwy pliku docelowego), w którym to przypadku basename od srcsłuży do tworzenia nowego pliku;Oto krótki przykład:
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
copyfilejest znacznie szybszy niżcopy2
shutil.copy2('/dir/file.ext', '/new/dir/')(z ukośnikiem za ścieżką docelową) usunie dwuznaczność, czy skopiować do nowego pliku o nazwie „katalog”, czy umieścić plik w katalogu o tej nazwie?
/new/diristnieje katalog, patrz komentarz @ MatthewAlpert.
/new/dir/nie istnieje, Python rzuci an IsADirectoryError, w przeciwnym razie kopiuje plik do /new/dir/oryginalnej nazwy.
Możesz użyć jednej z funkcji kopiowania z shutilpakietu:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Funkcja zachowuje obsługę obsługuje inne kopie
katalog uprawnień dest. plik obj metadane
―――――――――――――――――――――――――――――――――――――――――――――――――― ――――――――――――――――――――――――――――
shutil.copy ✔ ✔ ☐ ☐
shutil.copy2 ✔ ✔ ☐ ✔
shutil.copyfile ☐ ☐ ☐ ☐
shutil.copyfileobj ☐ ☐ ✔ ☐
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Przykład:
import shutil
shutil.copy('/etc/hostname', '/var/tmp/testhostname')
W Pythonie możesz kopiować pliki za pomocą
shutil modułos modułsubprocess modułimport os
import shutil
import subprocess
shutilmodułushutil.copyfile podpis
shutil.copyfile(src_file, dest_file, *, follow_symlinks=True)
# example
shutil.copyfile('source.txt', 'destination.txt')
shutil.copy podpis
shutil.copy(src_file, dest_file, *, follow_symlinks=True)
# example
shutil.copy('source.txt', 'destination.txt')
shutil.copy2 podpis
shutil.copy2(src_file, dest_file, *, follow_symlinks=True)
# example
shutil.copy2('source.txt', 'destination.txt')
shutil.copyfileobj podpis
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)
osmodułuos.popen podpis
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 podpis
os.system(command)
# In Linux/Unix
os.system('cp source.txt destination.txt')
# In Windows
os.system('copy source.txt destination.txt')
subprocessmodułusubprocess.call podpis
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 podpis
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]składni tam, gdzie to możliwe, szczególnie jeśli parametry pochodzą z danych wprowadzonych przez użytkownika.
os.popenjest przez pewien czas przestarzałe. i check_outputnie zwraca statusu, ale wyjście (które jest puste w przypadku copy/cp)
Kopiowanie pliku jest stosunkowo prostą operacją, jak pokazano w poniższych przykładach, ale zamiast tego powinieneś użyć do tego modułu 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)
Jeśli chcesz skopiować według nazwy pliku, możesz zrobić coś takiego:
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. Ponadto nie musisz try, finallyzajmować się zamykaniem plików po wyjątkach. Powiedziałbym jednak, że twoja funkcja nie powinna w ogóle odpowiadać za otwieranie i zamykanie plików. Powinno to przebiegać w funkcji otoki, np. Jak shutil.copyfileotacza shutil.copyfileobj.
destma być zapisywalny:open(dest, 'wb')
Użyj modułu Shutil .
copyfile(src, dst)
Skopiuj zawartość pliku o nazwie src do pliku o nazwie dst. Lokalizacja docelowa musi być zapisywalna; w przeciwnym razie zostanie zgłoszony wyjątek IOError. Jeśli dst już istnieje, zostanie zastąpione. Za pomocą tej funkcji nie można kopiować plików specjalnych, takich jak urządzenia znakowe lub blokowe oraz potoki. src i dst to nazwy ścieżek podane jako ciągi znaków.
Spójrz na system plików dla wszystkich funkcji obsługi plików i katalogów dostępnych w standardowych modułach Python.
Przykład skopiowania katalogu i pliku - z Tima Golden'a w Pythonie:
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"
Po pierwsze, stworzyłem wyczerpujący zestaw metod shutil dla twojego odniesienia.
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',]
}
Po drugie, wyjaśnij metody kopiowania w przykładach:
shutil.copyfileobj(fsrc, fdst[, length])manipulować otwartymi obiektami
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)Skopiuj i zmień nazwę
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()Kopiuj bez uprzedniego wyświetlania metadanych
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()Kopiuj z zachowaniem metadanych
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()
Rekurencyjnie skopiuj całe drzewo katalogów zrootowane na src, zwracając katalog docelowy
W przypadku małych plików i korzystania tylko z wbudowanych Pythona można użyć następującego jednowierszowego:
with open(source, 'rb') as src, open(dest, 'wb') as dst: dst.write(src.read())
Jak wspomniano w komentarzach @maxschlepzig, nie jest to optymalny sposób dla aplikacji, w których plik jest zbyt duży lub gdy pamięć jest krytyczna, dlatego należy preferować odpowiedź Swati .
.read()i .write()są buforowane domyślnie (przynajmniej dla CPython).
open()buforuje IO, domyślnie nie pomaga tutaj, ponieważ read()jest określony jako: „Jeśli n jest ujemne lub pominięte, czytaj do EOF”. Oznacza to, że read()zwraca całą zawartość pliku jako ciąg.
Możesz użyć os.system('cp nameoffilegeneratedbyprogram /otherdirectory/')
lub jak to zrobiłem
os.system('cp '+ rawfile + ' rawdata.dat')
gdzie rawfilejest nazwa, którą wygenerowałem w programie.
Jest to rozwiązanie tylko dla systemu Linux
shutilnie jest dostępny - subprocess.run() (bez shell=True!) Jest lepszą alternatywą dla os.system().
subprocess.run()jak sugeruje @maxschlepzig, to duży krok naprzód w przypadku wywoływania programów zewnętrznych. Jednak w celu zapewnienia elastyczności i bezpieczeństwa użyj ['cp', rawfile, 'rawdata.dat']formularza przekazania wiersza polecenia. (Jednak w przypadku kopiowania shutilzaleca się , aby znajomi zamiast wywoływać program zewnętrzny).
W przypadku dużych plików zrobiłem to, czytając plik linia po linii i czytając każdą linię w tablicy. Następnie, gdy tablica osiągnie określony rozmiar, dołącz ją do nowego pliku.
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)powinien znaleźć pracę; po prostu skonfiguruj bufor strumienia wyjściowego do swoich potrzeb. lub możesz przejść przez bajty, zapętlając próbę, output.write(read(n)); output.flush()gdzie njest liczba bajtów, którą chcesz zapisać na raz. oba z nich również nie mają warunku, aby sprawdzić, która premia.
shutil ? Nawet przy ignorowaniu shutilprosta blokowa pętla odczytu / zapisu (wykorzystująca niebuforowane We / Wy) jest prosta, byłaby wydajna i miałaby znacznie większy sens niż to, a zatem z pewnością jest łatwiejsza do nauczenia i zrozumienia.
from subprocess import call
call("cp -p <file> <file>", shell=True)
calljest niepewne. Proszę odnieść się do tego podproces docu na ten temat.
Począwszy od języka Python 3.5 , możesz wykonywać następujące czynności w przypadku małych plików (tj. Plików tekstowych, małych plików JPEG):
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 nadpisze wszystko, co było w miejscu docelowym
shutilobsługi wszystkich specjalnych przypadków dla ciebie i daje ci spokój.
open(destination, 'wb').write(open(source, 'rb').read())
Otwórz plik źródłowy w trybie odczytu i zapisz do pliku docelowego w trybie zapisu.
.close()wszystkich open(...)?
Python zapewnia wbudowane funkcje do łatwego kopiowania plików za pomocą narzędzi powłoki systemu operacyjnego.
Poniższe polecenie służy do kopiowania pliku
shutil.copy(src,dst)
Poniższe polecenie służy do kopiowania pliku z informacjami MetaData
shutil.copystat(src,dst)
copyNastępnie należy uruchomić, copystataby zachować metadane pliku. W Python 3.3+ copystatkopiuje także rozszerzone atrybuty.