Ответы:
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')
Используйте модуль shutil .
copyfile(src, dst)
Скопируйте содержимое файла с именем src в файл с именем dst. Место назначения должно быть доступно для записи; в противном случае возникнет исключение IOError. Если dst уже существует, он будет заменен. Специальные файлы, такие как символьные или блочные устройства и каналы, не могут быть скопированы с помощью этой функции. src и dst - это имена путей, заданные в виде строк.
Посмотрите на filesys все функции обработки файлов и каталогов, доступные в стандартных модулях Python.
Пример копирования каталога и файла - Из материала Питона Тима Голдена:
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',]
}
Во-вторых, объясните методы копирования в exmaples:
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()буферизированного ввода-вывода, по умолчанию здесь не помогает, поскольку 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простой цикл чтения / записи блока (с использованием небуферизованного ввода-вывода) является простым, эффективным и имеет гораздо больший смысл, чем этот, и, следовательно, его легче учить и понимать.
from subprocess import call
call("cp -p <file> <file>", shell=True)
callнебезопасно. Пожалуйста, обратитесь к документу subproces об этом.
Начиная с Python 3.5 вы можете делать следующее для небольших файлов (например: текстовые файлы, маленькие 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 перезапишет все, что было в месте назначения
shutilобрабатывает все особые случаи для вас и дает вам душевное спокойствие.
open(destination, 'wb').write(open(source, 'rb').read())
Откройте исходный файл в режиме чтения и запишите в целевой файл в режиме записи.
.close()по всем этим open(...)с?
Python предоставляет встроенные функции для простого копирования файлов с помощью утилит операционной системы.
Следующая команда используется для копирования файла
shutil.copy(src,dst)
Следующая команда используется для копирования файла с информацией метаданных
shutil.copystat(src,dst)
copyЗатем вы должны запустить, copystatчтобы сохранить метаданные файла. В Python 3.3+ copystatтакже копируются расширенные атрибуты.