Câu trả lời:
shutil
có nhiều phương pháp bạn có thể sử dụng. Một trong số đó là:
from shutil import copyfile
copyfile(src, dst)
Nếu bạn sử dụng các os.path
hoạt động, sử dụng copy
chứ không phải copyfile
. copyfile
sẽ chỉ chấp nhận chuỗi .
~
, nhưng nó có thể xử lý các đường dẫn tương đối
┌──────────────────┬────────┬───────────┬───────┬────────────────┐
│ 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)
thường hữu ích hơn copyfile(src,dst)
vì:
dst
là một thư mục (thay vì tên tệp đích hoàn chỉnh), trong trường hợp đó, tên cơ sở của src
được sử dụng để tạo tệp mới;Đây là một ví dụ ngắn:
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
nhanh hơn đáng kể so vớicopy2
shutil.copy2('/dir/file.ext', '/new/dir/')
(với dấu gạch chéo sau đường dẫn đích) sẽ loại bỏ sự mơ hồ về việc sao chép vào một tệp mới có tên là "dir" hay để đặt tệp vào một thư mục có tên đó?
/new/dir
là một thư mục hiện có, xem bình luận của @ MatthewAlpert.
/new/dir/
không tồn tại, Python sẽ ném một IsADirectoryError
tệp, nếu không nó sẽ sao chép tệp vào /new/dir/
dưới tên gốc.
Bạn có thể sử dụng một trong các chức năng sao chép từ shutil
gói:
Ăn miếng thịt ăn miếng thịt miếng, miếng thịt, miếng thịt Ăn vặt ăn thịt Chức năng bảo quản hỗ trợ chấp nhận các bản sao khác thư mục quyền mệnh. tập tin siêu dữ liệu obj -------------------------------------------------- ---------------------------- shutil.copy ✔ ✔ ☐ ☐ shutil.copy2 ✔ ✔ ☐ ✔ shutil.copyfile ☐ ☐ ☐ shutil.copyfileobj ☐ ✔ Ăn miếng thịt ăn miếng thịt miếng, miếng thịt, miếng thịt Ăn vặt ăn thịt
Thí dụ:
import shutil
shutil.copy('/etc/hostname', '/var/tmp/testhostname')
Trong Python, bạn có thể sao chép các tệp bằng cách sử dụng
shutil
mô-đunos
mô-đunsubprocess
mô-đunimport os
import shutil
import subprocess
shutil
mô-đunshutil.copyfile
Chữ ký
shutil.copyfile(src_file, dest_file, *, follow_symlinks=True)
# example
shutil.copyfile('source.txt', 'destination.txt')
shutil.copy
Chữ ký
shutil.copy(src_file, dest_file, *, follow_symlinks=True)
# example
shutil.copy('source.txt', 'destination.txt')
shutil.copy2
Chữ ký
shutil.copy2(src_file, dest_file, *, follow_symlinks=True)
# example
shutil.copy2('source.txt', 'destination.txt')
shutil.copyfileobj
Chữ ký
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
mô-đunos.popen
Chữ ký
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
Chữ ký
os.system(command)
# In Linux/Unix
os.system('cp source.txt destination.txt')
# In Windows
os.system('copy source.txt destination.txt')
subprocess
mô-đunsubprocess.call
Chữ ký
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
Chữ ký
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]
cú pháp bất cứ khi nào có thể, đặc biệt nếu các tham số là từ đầu vào của người dùng.
os.popen
bây giờ không được dùng nữa và check_output
không trả lại trạng thái nhưng đầu ra (trong trường hợp trống copy/cp
)
Sao chép một tập tin là một hoạt động tương đối đơn giản như được hiển thị bởi các ví dụ dưới đây, nhưng thay vào đó bạn nên sử dụng mô-đun stdlib đóng cửa cho điều đó.
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)
Nếu bạn muốn sao chép theo tên tệp, bạn có thể làm một cái gì đó như thế này:
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
. Ngoài ra, bạn không có bất kỳ try, finally
xử lý nào để đóng các tệp sau khi có ngoại lệ. Tuy nhiên, tôi muốn nói rằng chức năng của bạn không nên chịu trách nhiệm mở và đóng các tệp. Điều đó sẽ đi trong một chức năng bao bọc, như cách shutil.copyfile
kết thúc tốt đẹp shutil.copyfileobj
.
dest
để có thể ghi:open(dest, 'wb')
Sử dụng mô-đun đóng cửa .
copyfile(src, dst)
Sao chép nội dung của tệp có tên src vào một tệp có tên dst. Vị trí đích phải có thể ghi được; nếu không, một ngoại lệ IOError sẽ được đưa ra. Nếu dst đã tồn tại, nó sẽ được thay thế. Các tập tin đặc biệt như ký tự hoặc thiết bị khối và đường ống không thể được sao chép với chức năng này. src và dst là tên đường dẫn được cho dưới dạng chuỗi.
Hãy nhìn vào filesys cho tất cả các chức năng tập tin và xử lý thư mục có sẵn trong module Python chuẩn.
Ví dụ sao chép thư mục và tệp - Từ công cụ Python của 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"
Đầu tiên, tôi đã thực hiện một loạt các phương pháp đóng cửa để bạn tham khảo.
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',]
}
Thứ hai, giải thích các phương pháp sao chép trong exmaples:
shutil.copyfileobj(fsrc, fdst[, length])
thao tác mở các đối tượng
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)
Sao chép và đổi tên
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()
Sao chép mà không cần đặt trước siêu dữ liệu
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()
Sao chép với việc đặt trước siêu dữ liệu
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()
Đệ quy sao chép toàn bộ cây thư mục bắt nguồn từ src, trả về thư mục đích
Đối với các tệp nhỏ và chỉ sử dụng tích hợp python, bạn có thể sử dụng một lớp lót sau:
with open(source, 'rb') as src, open(dest, 'wb') as dst: dst.write(src.read())
Như @maxschlepzig đã đề cập trong các bình luận bên dưới, đây không phải là cách tối ưu cho các ứng dụng có tệp quá lớn hoặc khi bộ nhớ quan trọng, do đó , câu trả lời của Swati nên được ưu tiên.
.read()
và .write()
được đệm theo mặc định (ít nhất là cho CPython).
open()
IO được đệm, theo mặc định không giúp bạn ở đây, vì read()
được chỉ định là: 'Nếu n âm hoặc bị bỏ qua, hãy đọc cho đến khi EOF.' Điều đó có nghĩa là read()
trả về nội dung tệp hoàn chỉnh dưới dạng chuỗi.
Bạn đã có thể sử dụng os.system('cp nameoffilegeneratedbyprogram /otherdirectory/')
hoặc như tôi đã làm nó,
os.system('cp '+ rawfile + ' rawdata.dat')
Ở đâu rawfile
là tên mà tôi đã tạo ra bên trong chương trình.
Đây là một giải pháp duy nhất của Linux
shutil
không có sẵn - subprocess.run()
(không có shell=True
!) Là sự thay thế tốt hơn os.system()
.
subprocess.run()
như được đề xuất bởi @maxschlepzig là một bước tiến lớn, khi gọi các chương trình bên ngoài. Tuy nhiên, để linh hoạt và bảo mật, hãy sử dụng ['cp', rawfile, 'rawdata.dat']
hình thức chuyển dòng lệnh. (Tuy nhiên, để sao chép shutil
và bạn bè được khuyến nghị nên gọi một chương trình bên ngoài.)
Đối với các tệp lớn, những gì tôi đã làm là đọc từng dòng tệp và đọc từng dòng thành một mảng. Sau đó, khi mảng đạt đến một kích thước nhất định, hãy thêm nó vào một tệp mới.
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)
Nên tìm việc; chỉ cần thiết lập bộ đệm luồng đầu ra theo nhu cầu của bạn. hoặc bạn có thể đi bằng các byte bằng cách lặp qua một thử với output.write(read(n)); output.flush()
nơi n
là số byte mà bạn muốn ghi tại một thời điểm. cả hai điều này cũng không có điều kiện để kiểm tra xem đó là phần thưởng.
shutil
? Ngay cả khi bỏ qua shutil
, một vòng lặp đọc / ghi khối đơn giản (sử dụng IO không có bộ đệm) vẫn thẳng tiến, sẽ hiệu quả và có ý nghĩa hơn nhiều so với điều này, và do đó chắc chắn sẽ dễ dạy và hiểu hơn.
from subprocess import call
call("cp -p <file> <file>", shell=True)
call
là không an toàn. Vui lòng tham khảo tài liệu phụ về nó.
Kể từ Python 3.5, bạn có thể thực hiện các thao tác sau đối với các tệp nhỏ (ví dụ: tệp văn bản, tệp jpeg nhỏ):
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
sẽ ghi đè lên bất cứ thứ gì ở vị trí của điểm đến
shutil
xử lý tất cả các trường hợp đặc biệt cho bạn và giúp bạn yên tâm.
open(destination, 'wb').write(open(source, 'rb').read())
Mở tệp nguồn ở chế độ đọc và ghi vào tệp đích ở chế độ ghi.
.close()
những thứ open(...)
đó sao?
Python cung cấp các hàm dựng sẵn để dễ dàng sao chép các tệp bằng các tiện ích Shell của Hệ điều hành.
Lệnh sau được sử dụng để Sao chép tệp
shutil.copy(src,dst)
Lệnh sau được sử dụng để Sao chép tệp với Thông tin MetaData
shutil.copystat(src,dst)
copy
sau đó copystat
để bảo vệ siêu dữ liệu tập tin. Trong Python 3.3+ copystat
cũng sao chép các thuộc tính mở rộng.