9 Powerful Python Techniques to Copy Files Efficiently
Learn nine distinct Python approaches for copying files—including shutil functions, os commands, threading, and subprocess methods—while understanding their performance implications, error handling, platform compatibility, and when to choose each technique for optimal I/O efficiency.
Python provides many built‑in modules (such as
os,
subprocessand
shutil) to support file I/O operations. Choosing the most suitable file‑copy method is important because file I/O is performance‑intensive and can become a bottleneck. Different scenarios may require blocking, asynchronous, or platform‑specific approaches.
shutil
copyfile()method
shutil
copy()method
shutil
copyfileobj()method
shutil
copy2()method
os
popen()method
os
system()method
threading
Thread()method
subprocess
call()method
subprocess
check_output()method
shutil copyfile() method
This method copies the source file to the destination only when the target is writable; otherwise it raises an
IOError. It opens the source for reading, ignores file type, and does not preserve special files. Internally it uses the low‑level
copyfileobj()function, optionally accepting a buffer size.
<code>copyfile(source_file, destination_file)</code>Key points:
Copies source content to the destination file.
Raises
IOErrorif the destination is not writable.
Raises
SameFileErrorwhen source and destination are the same.
Overwrites existing files with a different name.
Fails with
Error 13if the destination is a directory.
Does not support copying character or block devices, pipes, etc.
shutil copy() method
Similar to the Unix
cpcommand. If the destination is a directory, a new file with the same base name is created inside it. After copying the data, the method also synchronises the destination file’s permissions with the source.
<code>copy(source_file, [destination_file or dest_dir])</code>Differences from
copyfile():
copy()can set permission bits while
copyfile()only copies data.
If the destination is a directory,
copy()succeeds;
copyfile()fails with
Error 13.
copy()internally calls
copyfile()and
copymode().
shutil copyfileobj() method
Copies the contents of a file object to another file object. An optional buffer size (default 16 KB) can be supplied to control the amount of data read into memory per block.
<code>from shutil import copyfileobj
status = False
if isinstance(target, string_types):
target = open(target, 'wb')
status = True
try:
copyfileobj(self.stream, target, buffer_size)
finally:
if status:
target.close()
</code>shutil copy2() method
Works like
copy()but also copies metadata such as access and modification times. It raises
SameFileErrorwhen source and destination refer to the same file.
Differences from
copy():
copy2()preserves timestamps in addition to permissions.
Internally it calls
copystat()instead of
copymode().
os popen() method
Creates a pipe to or from a command. Returns a file object connected to the pipe, which can be used for reading or writing (default mode is
r).
<code>os.popen(command[, mode[, bufsize]])</code>Parameters:
mode:
r(read) or
w(write).
bufsize: 0 (unbuffered), 1 (line buffered), >1 (buffered with given size), or negative (system default).
os system() method
Executes a system command in a subshell and returns the command’s exit status. It is a simple way to run external commands.
<code>os.system('copy 1.txt.py 2.txt.py') # Windows example
os.system('cp 1.txt.py 2.txt.py') # Linux example</code>Thread‑based file copy (asynchronous)
Uses the
threadingmodule to perform a copy operation in the background. Ensure proper locking when multiple threads access files to avoid deadlocks.
<code>import shutil
from threading import Thread
src = "1.txt.py"
dst = "3.txt.py"
Thread(target=shutil.copy, args=[src, dst]).start()
</code>subprocess call() method
Runs a command in a subprocess, waits for it to complete, and returns the exit code. It replaces older functions like
os.system,
os.spawn, and
os.popen.
<code>import subprocess
src = "1.txt.py"
dst = "2.txt.py"
cmd = 'copy "%s" "%s"' % (src, dst)
status = subprocess.call(cmd, shell=True)
if status != 0:
print("Command failed with return code", status)
else:
print("Execution of %s passed!" % cmd)
</code>subprocess check_output() method
Runs a command and captures its output. Useful when the result of the command is needed for further processing.
<code>import os, subprocess
src = os.path.realpath(os.getcwd() + "http://cdn.techbeamers.com/1.txt.py")
dst = os.path.realpath(os.getcwd() + "http://cdn.techbeamers.com/2.txt.py")
cmd = 'copy "%s" "%s"' % (src, dst)
status = subprocess.check_output(['copy', src, dst], shell=True)
print("status:", status.decode('utf-8'))
</code>These nine methods cover a range of use‑cases—from simple, high‑level copies with
shutilto low‑level system commands and asynchronous threading—allowing developers to select the most appropriate technique based on performance, portability, and error‑handling requirements.
Raymond Ops
Linux ops automation, cloud-native, Kubernetes, SRE, DevOps, Python, Golang and related tech discussions.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.