Fundamentals 12 min read

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.

Raymond Ops
Raymond Ops
Raymond Ops
9 Powerful Python Techniques to Copy Files Efficiently

Python provides many built‑in modules (such as os, subprocess and 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. copyfile(source_file, destination_file) Key points:

Copies source content to the destination file.

Raises IOError if the destination is not writable.

Raises SameFileError when source and destination are the same.

Overwrites existing files with a different name.

Fails with Error 13 if the destination is a directory.

Does not support copying character or block devices, pipes, etc.

shutil copy() method

Similar to the Unix cp command. 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.

copy(source_file, [destination_file or dest_dir])

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.

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()

shutil copy2() method

Works like copy() but also copies metadata such as access and modification times. It raises SameFileError when 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). os.popen(command[, mode[, bufsize]]) 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.

os.system('copy 1.txt.py 2.txt.py')  # Windows example
os.system('cp 1.txt.py 2.txt.py')    # Linux example

Thread‑based file copy (asynchronous)

Uses the threading module to perform a copy operation in the background. Ensure proper locking when multiple threads access files to avoid deadlocks.

import shutil
from threading import Thread
src = "1.txt.py"
dst = "3.txt.py"
Thread(target=shutil.copy, args=[src, dst]).start()

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.

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)

subprocess check_output() method

Runs a command and captures its output. Useful when the result of the command is needed for further processing.

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'))

These nine methods cover a range of use‑cases—from simple, high‑level copies with shutil to low‑level system commands and asynchronous threading—allowing developers to select the most appropriate technique based on performance, portability, and error‑handling requirements.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

File I/Othreadingshutilsubprocesscopyfile
Raymond Ops
Written by

Raymond Ops

Linux ops automation, cloud-native, Kubernetes, SRE, DevOps, Python, Golang and related tech discussions.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.