How to copy files in Python

Posted in Python by Dirk - last update: Feb 06, 2024

The choice of method depends on the specific use case and preferences. shutil.copy and shutil.copy2 are generally recommended for simplicity, while pathlib and file streams provide a more granular control.

Using shutil module’s copy method

The shutil.copy function is part of the shutil module and provides a high-level interface for file operations. It copies the contents of the source file to the destination file.

import shutil

source_path = 'path/to/source/file.txt'
destination_path = 'path/to/destination/file.txt'

shutil.copy(source_path, destination_path)
  • Pro: Simple and convenient.
  • Cons: If the destination file already exists, it will be overwritten without warning. Not suitable for copying directories.

Using shutil module’s copy2 method

Similar to shutil.copy, shutil.copy2 also copies the contents of the source file to the destination file. The key difference is that it also copies metadata (such as timestamps) from the source to the destination.

import shutil

source_path = 'path/to/source/file.txt'
destination_path = 'path/to/destination/file.txt'

shutil.copy2(source_path, destination_path)
  • Pro: Retains metadata from the source file.
  • Con: Same as shutil.copy, doesn’t work for directories and if the destination file exists, it will be overwritten

Using shutil module’s copyfile method

Similar to shutil.copy, shutil.copyfile also copies the contents of the source file to the destination file. The key difference is that it only copies the content - no metadata (such as timestamps) but also no permissions from the source to the destination.

import shutil

source_path = 'path/to/source/file.txt'
destination_path = 'path/to/destination/file.txt'

shutil.copyfile(source_path, destination_path)
  • Pro: Barebones copy function.
  • Con: Same as shutil.copy, doesn’t work for directories and if the destination file exists, it will be overwritten

Using shutil module’s copyfileobj method

The shutil.copyfileobj method copies the contents of the source file object to the destination file object. In this example, the source and destination files are opened using open, and their file objects are passed to copyfileobj.

import shutil

source_path = 'path/to/source/file.txt'
destination_path = 'path/to/destination/file.txt'

with open(source_path, 'rb') as source_file, open(destination_path, 'wb') as dest_file:
    shutil.copyfileobj(source_file, dest_file)
  • Pros: Allows more flexibility by specifying custom file objects. Particularly useful if to copy files when the files are already open.
  • Cons: Like shutil.copyfile, it doesn’t copy metadata. The burden of file opening and handling is on the developer.

Using file streams

This method opens the source file in binary read mode and the destination file in binary write mode. It reads the content from the source file and writes it to the destination file.

source_path = 'path/to/source/file.txt'
destination_path = 'path/to/destination/file.txt'

with open(source_path, 'rb') as source_file, open(destination_path, 'wb') as dest_file:
    dest_file.write(source_file.read())
  • Pros: Fine-grained control over file reading and writing.
  • Cons: Manual handling of file operations, not as concise as shutil methods.

Using pathlib

pathlib is a module introduced in Python 3.4 for object-oriented file system paths. This example uses Path objects to read and write file content.

from pathlib import Path

source_path = Path('path/to/source/file.txt')
destination_path = Path('path/to/destination/file.txt')

source_path.write_bytes(destination_path.read_bytes())
  • Pros: Object-oriented approach, concise code.
  • Cons: May not be as familiar to developers who are used to traditional file operations.

Using os.popen or os.system

While technically possible these methods are not recommended as they introduce platform dependency in a platform-independent language.

Using subprocess module

Similar to the os.popen or os.system methods, While technically possible this method is not recommended as it introduces platform dependency in a platform-independent language.

Other articles