How to copy files?
2,815,586
Solution 1
shutil
has many methods you can use. One of which is:
import shutil
shutil.copyfile(src, dst)
# 2nd option
shutil.copy(src, dst) # dst can be a folder; use shutil.copy2() to preserve timestamp
- Copy the contents of the file named
src
to a file nameddst
. Bothsrc
anddst
need to be the entire filename of the files, including path. - The destination location must be writable; otherwise, an
IOError
exception will be raised. - If
dst
already exists, it will be replaced. - Special files such as character or block devices and pipes cannot be copied with this function.
- With
copy
,src
anddst
are path names given asstr
s.
Another shutil
method to look at is shutil.copy2()
. It's similar but preserves more metadata (e.g. time stamps).
If you use os.path
operations, use copy
rather than copyfile
. copyfile
will only accept strings.
Solution 2
Function | Copies metadata |
Copies permissions |
Uses file object | Destination 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 |
Solution 3
copy2(src,dst)
is often more useful than copyfile(src,dst)
because:
- it allows
dst
to be a directory (instead of the complete target filename), in which case the basename ofsrc
is used for creating the new file; - it preserves the original modification and access info (mtime and atime) in the file metadata (however, this comes with a slight overhead).
Here is a short example:
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
Solution 4
In Python, you can copy the files using
-
shutil
module -
os
module -
subprocess
module
import os
import shutil
import subprocess
1) Copying files using shutil
module
shutil.copyfile
signature
shutil.copyfile(src_file, dest_file, *, follow_symlinks=True)
# example
shutil.copyfile('source.txt', 'destination.txt')
shutil.copy
signature
shutil.copy(src_file, dest_file, *, follow_symlinks=True)
# example
shutil.copy('source.txt', 'destination.txt')
shutil.copy2
signature
shutil.copy2(src_file, dest_file, *, follow_symlinks=True)
# example
shutil.copy2('source.txt', 'destination.txt')
shutil.copyfileobj
signature
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)
2) Copying files using os
module
os.popen
signature
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
signature
os.system(command)
# In Linux/Unix
os.system('cp source.txt destination.txt')
# In Windows
os.system('copy source.txt destination.txt')
3) Copying files using subprocess
module
subprocess.call
signature
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
signature
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)
Solution 5
You can use one of the copy functions from the shutil
package:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Function preserves supports accepts copies other permissions directory dest. file obj metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― shutil.copy ✔ ✔ ☐ ☐ shutil.copy2 ✔ ✔ ☐ ✔ shutil.copyfile ☐ ☐ ☐ ☐ shutil.copyfileobj ☐ ☐ ✔ ☐ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Example:
import shutil
shutil.copy('/etc/hostname', '/var/tmp/testhostname')
Comments
-
Matt almost 2 years
How do I copy a file in Python?
-
pi. about 15 yearsI noticed a while ago that the module is called shutil (singular) and not shutils (plural), and indeed it is in Python 2.3. Nevertheless I leave this function here as an example.
-
Kevin Horn over 14 yearsNote that not all metadata will be copied, depending on your platform.
-
Vijay about 10 yearsI am trying to randomly copy 100k files from 1 million files.
copyfile
is considerably faster thancopy2
-
owns almost 9 yearsthis seems a little redundant since the writer should handle buffering.
for l in open('file.txt','r'): output.write(l)
should work find; just setup the output stream buffer to your needs. or you can go by the bytes by looping over a try withoutput.write(read(n)); output.flush()
wheren
is the number of bytes you'd like to write at a time. both of these also don't have an condition to check which is a bonus. -
rassa45 almost 9 yearsYes, but I thought that maybe this could be easier to understand because it copies entire lines rather than parts of them (in case we don't know how many bytes each line is).
-
owns almost 9 yearsVery true. Coding for teaching and coding for efficiency are very different.
-
Kevin Meier over 7 yearsThis depends on the platform, so i would not use is.
-
rassa45 over 7 years@owns To add to this question a year later,
writelines()
has shown slightly better performance overwrite()
since we don't waste time consistently opening a new filestream, and instead write new lines as one large bytefeed. -
buhtz about 7 yearsSuch a
call
is unsecure. Please refere to the subproces docu about it. -
owns about 7 yearslooking at the source - writelines calls write, hg.python.org/cpython/file/c6880edaf6f3/Modules/_io/bytesio.c. Also, the file stream is already open, so write wouldn't need to reopen it every time.
-
Corey Goldberg almost 7 yearsthis is not portable, and unnecessary since you can just use shutil.
-
Corey Goldberg almost 7 yearsthis is not portable, and unnecessary since you can just use shutil.
-
Baris Demiray almost 7 yearsHmm why Python, then?
-
maxschlepzig almost 7 yearsEven when
shutil
is not available -subprocess.run()
(withoutshell=True
!) is the better alternative toos.system()
. -
waterbyte over 5 yearsNote that it is not an atomic operation. Take care using it in a threaded application.
-
MilkyWay90 over 5 yearsMaybe detect the operating system before starting (whether it's DOS or Unix, because those are the two most used)
-
zwep over 5 yearsNote that it cant handle abbreviations like
~
, but it can deal with relative paths -
Jack M over 5 years@Owen Indeed it can, but the directory has to already exist. By the way, as long as the target directory already exists,
dst
can either end or not end with a trailing slash, it doesn't matter. -
Alexei Martianov over 5 yearsTo create all intermediate-level destination directories you could use os.makedirs() before copying, details here stackoverflow.com/questions/12842997/…
-
Hiadore about 5 yearsshutil is more portable
-
Raúl Salinas-Monteagudo about 5 yearsThe idea is nice and the code is beautiful, but a proper copy() function can do more things, such as copying attributes (+x bit), or for example deleting the already-copied bytes in case a disk-full condition is found.
-
miike3459 about 5 yearsAll answers need explanation, even if it is one sentence. No explanation sets bad precedent and is not helpful in understanding the program. What if a complete Python noob came along and saw this, wanted to use it, but couldn't because they don't understand it? You want to be helpful to all in your answers.
-
luckydonald about 5 yearsIsn't that missing the
.close()
on all of thoseopen(...)
s? -
Sundeep471 about 5 yearsNo need of .close(), as we are NOT STORING the file pointer object anywhere(neither for the src file nor for the destination file).
-
Marcel Waldvogel about 5 yearsUsing single-string commands is bad coding style (flexibility, reliability and security), instead use
['copy', sourcefile, destfile]
syntax wherever possible, especially if the parameters are from user input. -
Marcel Waldvogel about 5 years
subprocess.run()
as suggested by @maxschlepzig is a big step forward, when calling external programs. For flexibility and security however, use the['cp', rawfile, 'rawdata.dat']
form of passing the command line. (However, for copying,shutil
and friends are recommended over calling an external program.) -
Marcel Waldvogel about 5 yearsAFAIK, it is undefined when the files are actually closed, @SundeepBorra. Using
with
(as in the example above) is recommended and not more complicated. Usingread()
on a raw file reads the entire file into memory, which may be too big. Use a standard function like fromshutil
so that you and whoever else is involved in the code does not need to worry about special cases. docs.python.org/3/library/io.html#io.BufferedReader -
Marcel Waldvogel about 5 yearsAnd then someone uses the code (accidentally or purposefully) on a large file… Using functions from
shutil
handles all the special cases for you and gives you peace of mind. -
maxschlepzig about 5 yearsSame suboptimal memory-wasting approach as yellow01's answer.
-
maxschlepzig about 5 yearsWhy do you list so many bad alternatives to the shutil copy functions?
-
Jean-François Fabre about 5 yearsshutil is built-in, no need to provide non-portable alternatives. The answer could be actually improved by removing the system dependent solutions, and after that removal, this answer is just a copy of the existing answers / a copy of the documentation.
-
Jean-François Fabre about 5 yearstry that with filenames with spaces in it.
-
Jean-François Fabre about 5 years
os.popen
is deprecated for a while now. andcheck_output
doesn't return the status but the output (which is empty in the case ofcopy/cp
) -
Jean-François Fabre about 5 yearsat least it doesn't repeat the same solutions over and over again.
-
maxschlepzig about 5 yearsThis is awful. It does unnecessary work for no good reason. It doesn't work for arbitrary files. The copy isn't byte-identical if the input has unusual line endings on systems like Windows. Why do you think that this might be easier to understand than a call to a copy function in
shutil
? Even when ignoringshutil
, a simple block read/write loop (using unbuffered IO) is straight forward, would be efficient and would make much more sense than this, and thus is surely easier to teach and understand. -
gman over 4 yearsshutil does not actually copy files. There's a big fat warning right at the top of the docs. "this means that file owner and group are lost as well as ACLs. On Mac OS, the resource fork and other metadata are not used. This means that resources will be lost and file type and creator codes will not be correct. On Windows, file owners, ACLs and alternate data streams are not copied."
-
gman over 4 yearsshutil does not actually copy files. There's a big fat warning right at the top of the docs. "this means that file owner and group are lost as well as ACLs. On Mac OS, the resource fork and other metadata are not used. This means that resources will be lost and file type and creator codes will not be correct. On Windows, file owners, ACLs and alternate data streams are not copied."
-
Martijn Pieters about 4 yearsThis also adds decoding / encoding overhead, and won’t work on binary data. Just use
shutil.copyfile()
, which on 3.8 has been improved further to use native OS support for fast file copying. It easily will take less than half the time from what this answer will take. -
Martijn Pieters about 4 yearsIn Python 3.8 this has received some significant speed boosts (~50% faster, depending on OS).
-
ingyhere almost 4 yearsYou should run
copy
thencopystat
to preserve file metadata. In Python 3.3+copystat
also copies extended attributes. -
Debvrat Varshney almost 4 yearscopy or copyfile does not seem to replace the file if dst already exists 🤔. Getting a SameFileError
-
AO_ over 3 yearsIf you want some pictures to help with clarity: ao.gl/how-to-copy-a-file-in-python
-
KansaiRobot almost 3 yearsdst as a folder throws an exception
-
Scrooge McDuck over 2 yearsequivalent of
cp
-
Admin over 2 yearsYour answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
-
Eric Aya over 2 yearsThis has already been mentioned in the other answers. When answering older questions that already have answers, please make sure you provide either a novel solution or a significantly better explanation than existing answers.
-
user3804598 over 2 yearsit handles relative paths nicely
-
kontur over 2 yearsAnd if the file name remains, you can copy to the destination folder:
shutil.copy(os.path.join(old_dir, file), new_dir)
-
wovano about 2 years
-
t3chb0t about 2 yearsWhat a mess! Who designed these APIs :-\
-
t3chb0t about 2 years@Jean-FrançoisFabre System dependent solutions is exactly what I was looking for. The question is how to copy files in general not necessarily in a system-independet way so this answer is perfectly valid.
-
otocan almost 2 yearsNote that shutil.copy also allows
dest
to be a directory, at least in current versions (I'm using python 3.8)