How to Copy a File Using Python: Explained WIth Examples

by | Python

Copying files is a common task in programming, and Python provides simple and efficient ways to perform this operation. In this article, you’ll learn several different methods and how to choose the best approach for your specific needs.

Copying a file in Python is a straightforward task that can be accomplished using the shutil module’s copy() function. First, you import the shutil module, and then you call the shutil.copy(source, destination) function, where ‘source’ is the path of the file you want to copy, and ‘destination’ is the directory where you want the copied file to be placed.

Whether you need to copy files between directories, preserve metadata, or apply customized operations, Python has you covered with its powerful and intuitive syntax.

How to Import the Shutil Module in Python

If you intend to use the shutil module to copy a file in Python, you’ll first need to import it. This is a built-in Python module that provides functions for high-level file operations, such as copying and moving files.

To import the shutil module, simply add the following line of code:

import shutil
how to copy a file using python

You may also find the os module useful for working with file paths. For example, os.path.join will let you join path segments to create a complete path.

3 Ways to Copy Files Using Shutil Functions

The shutil module provides three different functions for copying files in Python:

  • shutil.copy()
  • shutil.copyfile()
  • shutil.copy2()

Each has slightly different ways of dealing with permissions and metadata (e.g., the file creation time).

1. How to Use Shutil.Copy

The shutil.copy function allows you to copy the content of a source file to a destination file or directory while preserving the file’s permission mode. However, it does not preserve other metadata like the file’s creation and modification times.

To use shutil copy, import the module and then call the function with the source and destination paths.

import shutil

src = 'source_file.txt'
dst = 'destination_file.txt'

shutil.copy(src, dst)

2. How to Use Shutil.Copyfile

The shutil.copyfile function is used when you need to copy the contents of a source file to a destination file, without preserving any metadata or file permissions. This method is useful when you only care about the file contents and not additional information.

Here’s an example of how to use shutil.copyfile:

import shutil

src = 'source_file.txt'
dst = 'destination_file.txt'

shutil.copyfile(src, dst)

3. How to Use Shutil.Copy2

shutil.copy2 is similar to shutil.copy, but it also preserves the file’s metadata, including timestamps (creation and modification times). This is useful when you need to maintain the original attributes of the file during the copying process.

It also allows the destination folder to be a directory instead of the complete target filename.

To use shutil.copy2, import the module and call the function with the source and destination paths, like so:

import shutil

src = 'source_file.txt'
dst = 'destination_file.txt'

shutil.copy2(src, dst)

All three of these functions (shutil.copy, shutil.copyfile, and shutil.copy2) offer different degrees of control over what information is preserved when copying files in Python.

Choose the one that best suits your particular use case when working with file operations.

illustration of copying files

Understanding File Metadata in Python

File metadata provides crucial information about a file, like its creation date, modification time, and file permissions. When working with files in Python, it’s often essential to understand and interact with this metadata properly.

3 Types of Permissions

File permissions control who can access a file and what they can do with it. There are three types of permissions:

  1. read (r)
  2. write (w)
  3. execute (x)

These permissions are assigned to three categories of users:

  1. the file’s owner
  2. the file’s group
  3. others.

Understanding permissions is essential when copying a file, as you may need to preserve the original file’s permissions in the copied file.

You can use Python’s os and stat libraries to retrieve and modify file permissions. For instance, you can obtain a file’s permission bits using os.stat(file_path).st_mode and then utilize stat.S_IMODE to extract the permission bits.

Here is sample code:

import os, stat

src = 'source_file.txt'

print(stat.S_IMODE(os.stat(src).st_mode))

When copying a file, you can use the shutil.copy2() function to preserve both the file’s metadata and permissions.

Symlinks

illustration of symbolic link to a file

A symlink, or symbolic link, is a special type of file that serves as a reference to another file or directory. Symlinks are useful for creating shortcuts, allowing multiple locations to point to a single file, or organizing files across various directories.

When copying files in Python, it is crucial to understand how symlinks should be treated.

By default, functions like shutil.copy() and shutil.copy2() will follow symlinks and copy the actual files they point to. However, these functions have an optional argument follow_symlinks.

When set to False, they will copy the symlink itself instead of the target file. This can be useful if you want to preserve the structure of symlinks in your copied files.

shutil.copy(src, dst, follow_symlinks=False)
illustration of copying files

2 Advanced Copying Techniques in Python

These two advanced techniques provide more flexibility and control over the copying process:

  1. copying file objects
  2. copying directories

1. How to Copy File Objects With Shutil.Copyfileobj

shutil.copyfileobj is a versatile function that allows you to copy files using file objects instead of file paths. This can be useful when working with files in memory or files that are opened in a specific mode.

To use shutil.copyfileobj, you need to open both the source and destination files in binary mode. The source file object is opened in read mode while the destination file is opened in write mode.

You can also specify an optional buffer size parameter to control the size of the buffer used during copying. Here’s an example:

import shutil

# Open source and destination files in binary mode
with open('source_file.bin', 'rb') as src, open('destination_file.bin', 'wb') as dst:
    # Copy the file objects with a buffer size of 8KB
    shutil.copyfileobj(src, dst, length=8*1024)

2. How to Copy Directories With Shutil.Copytree

When you need to copy entire directories (including sub-directories), shutil.copytree is an efficient solution. This function takes two arguments — the source and destination folder paths.

The command in the format “shutil.copytree(src, dst)” will recursively copy an entire directory tree rooted at src to the destination directory. Note that the destination path shouldn’t already exist.

You can provide an optional ignore parameter to specify a function that determines which files or folders should be ignored during the copying process.

Here’s an example of how to use shutil.copytree:

import shutil

source_dir = 'path/to/source/directory'
destination_dir = 'path/to/destination/directory'

def ignore_function(dir, names):
    return ['ignore_this_file.txt']

# Copy source directory to destination directory
shutil.copytree(source_dir, destination_dir, ignore=ignore_function)

In the example above, the ignore_function ignores a specific file during the copying process.

You can further customize this function to implement more complex ignore patterns. Be sure to comment your code so that others can easily understand the patterns.

When you’re working with large data sets in multiple files, these commands come in handy.

Error Handling and Exceptions When Copying Files in Python

When copying files in Python, it’s essential to handle errors and exceptions appropriately to ensure smooth execution.

This section looks at common exceptions you are likely to encounter in your operations. Then you’ll learn how to handle these exceptions.

illustration of error

4 Common Exceptions

  • IOError/ OSError: Occurs when the file cannot be opened or read, typically due to file permission or non-existent file issues.
  • IsADirectoryError: Raised when trying to copy a directory, instead of a file.
  • SameFileError: Occurs when the source and destination file paths are identical.
  • FileNotFoundError: Raised when the specified file cannot be found.

To handle these exceptions, you can use the try-except block in your code. For example:

import os
import shutil

src_file = 'source_file_path'
dst_file = 'destination_file_path'

try:
    if os.path.islink(src_file):
        src_file = os.readlink(src_file)
    shutil.copyfile(src_file, dst_file)
except FileNotFoundError:
    print("Unable to find the file")
except IsADirectoryError:
    print("The specified source is a directory, not a file")
except FileNotFoundError:
    print("Cannot find the specified file")

If you want to learn more about error handling, our article on Python’s try/except statements will help you.

Custom Error Handling

To implement custom error handling for your file copy operation, you can define your own exception classes. For example, to handle image file operations, you can create a custom exception class as follows:

class ImageCopyError(Exception):
    pass

To raise and handle this exception, use the try-except block in your code:

import os
import shutil

def is_image(file_path):
    # Your logic to check if the file is an image
    pass

src_file = 'source_image_file_path'
dst_file = 'destination_image_file_path'

try:
    if not is_image(src_file):
        raise ImageCopyError("Not an image file")
    shutil.copyfile(src_file, dst_file)
except ImageCopyError as e:
    print(f"Error: {e}")

How to Run External Copy Commands in Python

In this section, you’ll learn how to run external copy commands using Python. In other words, this involves calling shell commands from inside your Python script.

illustration of cp command on the command line

1. How to Use Os.Popen

The os.popen method allows you to execute shell commands from your Python script. To use this method for copying files, you first need to import the os module.

The following example demonstrates how to copy a file using the shell’s copy command and os.popen:

import os

source_file = '/path/to/source_file.txt'
destination_file = '/path/to/destination_file.txt'

# Execute the copy command
copy_command = f'cp {source_file} {destination_file}'
os.popen(copy_command)

Keep in mind that the above code uses the cp command, which is specific to a Unix-based operating system. For Windows systems, replace cp with copy.

2. How to Use the Subprocess Module

The subprocess module provides a more powerful and flexible way to run external commands in Python. The subprocess.run() function is the recommended method for interacting with the shell, as it ensures better error handling.

To use the subprocess module to copy files, follow these steps:

  1. Import the subprocess module.
  2. Define the source and destination file paths.
  3. Run the subprocess.run() function with the appropriate copy command.

Here’s an example:

import subprocess

source_file = '/path/to/source_file.txt'
destination_file = '/path/to/destination_file.txt'

# Execute the copy command
copy_command = ['cp', source_file, destination_file]
subprocess.run(copy_command)

Similar to the previous example, you should replace cp with copy when working on Windows systems.

Final Thoughts

You have learned several different methods for copying files in Python. Some offer simplicity while others are a better choice for complex requirements.

When working with files in Python, portability is an important consideration. The shutil and os libraries help maintain portability across different operating systems, making your code more versatile and useful in various scenarios.

By using these built-in libraries, you enable your file operations to run smoothly on different platforms without having to worry about compatibility issues.

Related Posts