Відповіді:
shutilє багато методів, якими ви можете скористатися. Один з яких:
from shutil import copyfile
copyfile(src, dst)
Якщо ви використовуєте os.pathоперації, copyскоріше використовуйте copyfile. copyfileбуде приймати тільки рядок .
~, але він може мати відносні шляхи
┌──────────────────┬────────┬───────────┬───────┬────────────────┐
│ 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)часто корисніше, ніж copyfile(src,dst)тому, що:
dstбути каталог (замість повного цільового файлу), в цьому випадку базовий з srcвикористовуються для створення нового файлу;Ось короткий приклад:
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значно швидше, ніжcopy2
shutil.copy2('/dir/file.ext', '/new/dir/')(з косою рискою за цільовим контуром) усуне неоднозначність щодо того, чи потрібно копіювати в новий файл під назвою "dir", або вставити файл у каталог з таким ім'ям?
/new/dirце вже існуючий каталог, дивіться коментар @ MatthewAlpert.
/new/dir/його не існує, Python викине IsADirectoryErrorфайл, інакше він копіює файл /new/dir/під оригінальним іменем.
Ви можете використовувати одну з функцій копіювання з shutilпакета:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Функція зберігає підтримку, приймає копії інших
довідник дозволів dest. метадані файлу obj
―――――――――――――――――――――――――――――――――――――――――――――――――― ――――――――――――――――――――――――――――
shutil.copy ✔ ✔ ☐ ☐
shutil.copy2 ✔ ✔ ☐ ✔
shutil.copyfile ☐ ☐ ☐ ☐
shutil.copyfileobj ☐ ☐ ✔ ☐
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Приклад:
import shutil
shutil.copy('/etc/hostname', '/var/tmp/testhostname')
У Python ви можете скопіювати файли за допомогою
shutil модульos модульsubprocess модульimport os
import shutil
import subprocess
shutilмодуляshutil.copyfile підпис
shutil.copyfile(src_file, dest_file, *, follow_symlinks=True)
# example
shutil.copyfile('source.txt', 'destination.txt')
shutil.copy підпис
shutil.copy(src_file, dest_file, *, follow_symlinks=True)
# example
shutil.copy('source.txt', 'destination.txt')
shutil.copy2 підпис
shutil.copy2(src_file, dest_file, *, follow_symlinks=True)
# example
shutil.copy2('source.txt', 'destination.txt')
shutil.copyfileobj підпис
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модуляos.popen підпис
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 підпис
os.system(command)
# In Linux/Unix
os.system('cp source.txt destination.txt')
# In Windows
os.system('copy source.txt destination.txt')
subprocessмодуляsubprocess.call підпис
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 підпис
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]синтаксис, де це можливо, особливо якщо параметри надходять з користувальницьких даних.
os.popenна деякий час застаріла. і check_outputне повертає статус, але вихід (який у випадку порожній copy/cp)
Копіювання файлу є відносно простою операцією, як показано на прикладах нижче, але замість цього слід використовувати модуль 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)
Якщо ви хочете скопіювати ім’я файлу, ви можете зробити щось подібне:
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. Крім того, у вас немає жодних try, finallyможливостей обробляти закриття файлів після винятку. Однак я б сказав, що ваша функція взагалі не повинна відповідати за відкриття та закриття файлів. Це має виконувати функцію обгортки, як, наприклад, як shutil.copyfileобгортання shutil.copyfileobj.
destщо підлягає запису:open(dest, 'wb')
Використовуйте шутильний модуль .
copyfile(src, dst)
Скопіюйте вміст файла з ім'ям src у файл з назвою dst. Місце призначення повинно бути записаним; інакше буде піднято виняток IOError. Якщо dst вже існує, його буде замінено. Спеціальні файли, такі як символьні або блокові пристрої та труби, не можна скопіювати за допомогою цієї функції. src і dst - це назви шляхів, задані у вигляді рядків.
Ознайомтеся з файлами файлів для всіх функцій обробки файлів і каталогів, доступних у стандартних модулях Python.
Приклад копіювання каталогів та файлів - із матеріалу Python Tim Tim Golden:
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"
По-перше, я зробив вичерпний чіт-лист шутильних методів для вашої довідки.
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',]
}
По-друге, поясніть методи копіювання у прикладах:
shutil.copyfileobj(fsrc, fdst[, length])маніпулювати відкритими предметами
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)Скопіюйте та перейменуйте
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()Скопіюйте без попереднього встановлення метаданих
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()Скопіюйте за допомогою попереднього налаштування метаданих
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()
Рекурсивно копіюйте ціле дерево каталогів, вкорінене в src, повертаючи каталог призначення
Для невеликих файлів та використання лише вбудованих файлів python ви можете використовувати наступний однокласник:
with open(source, 'rb') as src, open(dest, 'wb') as dst: dst.write(src.read())
Як @maxschlepzig згадується в коментарях нижче, це не оптимальний спосіб для додатків, де файл занадто великий або коли пам'ять критична, тому відповіді Сваті слід віддавати перевагу.
.read()і .write()вони буферизовані за замовчуванням (принаймні для CPython).
open()буферизованим IO, за замовчуванням не допомагає вам тут, тому що read()вказано як: "Якщо n від'ємне чи пропущене, читайте до EOF." Це означає, що read()повертає весь вміст файлу у вигляді рядка.
Ви можете використовувати os.system('cp nameoffilegeneratedbyprogram /otherdirectory/')
або як я це зробив,
os.system('cp '+ rawfile + ' rawdata.dat')
де rawfileназва, яку я створив всередині програми.
Це єдине рішення для Linux
shutilце недоступно - краща альтернатива - subprocess.run() (без shell=True!) os.system().
subprocess.run()як запропонував @maxschlepzig - це великий крок вперед під час виклику зовнішніх програм. Для гнучкості та безпеки використовуйте ['cp', rawfile, 'rawdata.dat']форму передачі командного рядка. (Однак для копіювання shutilдрузям рекомендується дзвонити до зовнішньої програми.)
Для великих файлів я читав файл за рядком і читав кожен рядок у масиві. Потім, як тільки масив досяг певного розміру, додайте його до нового файлу.
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)слід працювати знайти; просто налаштуйте буфер вихідного потоку під свої потреби. або ви можете перейти за байтами, переглянувши спробу, output.write(read(n)); output.flush()де nкількість байтів, які ви хотіли б написати за один раз. вони також не мають умови перевірити, що є бонусом.
shutil? Навіть при ігноруванні shutilпростий блок циклу читання / запису (використовуючи нерозподілений IO) прямо вперед, був би ефективним і мав би набагато більше сенсу, ніж це, і, таким чином, напевно легше навчати та розуміти.
from subprocess import call
call("cp -p <file> <file>", shell=True)
callє незахищеним. Будь ласка, ознайомтесь із документацією щодо цього підпроцесу.
З Python 3.5 ви можете зробити наступне для невеликих файлів (тобто: текстові файли, невеликі jpegs):
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 буде замінено те, що було в місці призначення
shutilобробки всіх особливих випадків для вас і дає вам спокій.
open(destination, 'wb').write(open(source, 'rb').read())
Відкрийте вихідний файл у режимі читання та запишіть у цільовий файл у режимі запису.
.close()на всіх цих open(...)s?
Python пропонує вбудовані функції для легкого копіювання файлів за допомогою утилітів оболонки операційної системи.
Наступна команда використовується для копіювання файлу
shutil.copy(src,dst)
Наступна команда використовується для копіювання файлу з інформацією про метадані
shutil.copystat(src,dst)
copyПотім слід запустити, copystatщоб зберегти метадані файлів. У Python 3.3+ copystatтакож копіюються розширені атрибути.