Often software developers need to copy files and directories from one disk location to another. Typically, they use terminal commands such as cp or mv for this purpose. But sometimes, you may need to copy files within your Python application/website at the click of a button or when some other event is triggered. In this case, you will need to programmatically copy files using Python. This is also true in case you need to copy files in bulk. There are several ways to solve this problem. In this article, we will learn how copy files in Python.
How to Copy Files in Python
Here are the different ways to copy files in Python.
1. Using Shutil Module
Shutil is a popular Python module that offers many high-level functions to copy or delete one or more files and folders. There are several different functions specifically available to copy files. Let us look at the important ones.
Using shutil.copyfile function
The copyfile function easily copies file contents from one location to another. However, it does not copy file metadata. Here is its syntax.
shutil.copyfile(source, destination, *, follow_symlinks=True)
In the above command, you need to specify the source and destination paths for the file, as strings. The remaining 2 arguments are optional. If the follow_symlink option is true, then a file copy is created in destination, if the source is a symbolic link. Else the destination will also be a symbolic link.
Please note, the system user executing this command must have write permission for destination directory. Otherwise, it will raise OSError. Here is an example to copy file from /home/ubuntu/data.txt to /home/ubuntu/project.txt.
shutil.copyfile('/home/ubuntu/data.txt', '/home/ubuntu/project.txt')
As the name suggests, it can be used to copy files only. It does not support copying of directories.
Using shutil.copy function
shutil.copy() function will allow you to easily copy files as well as directories. Here is its syntax.
shutil.copy(source, destination, *, follow_symlinks=True)
The first argument is the path of source file to be copied. The second argument is a path to file or folder. If it is a path to a directory, then the file is copied to this directory using the same file name as that of source file. If it is a file path that exists, then the destination file is overwritten with the file content of source file. Otherwise, it will create a new file as per the destination file path.
The copy() function copies file’s data and permissions. It does not copy file’s metadata such as creation date & modification date. If follow_symlinks is set to false, it will create destination as a symbolic link. If it is true, then destination will be a copy of the source.
Here is an example to copy file using this command.
shutil.copy('/home/ubuntu/data.txt','/home/ubuntu/project.txt')
Using shutil.copy2 function
The shutil.copy2() function works exactly like shutil.copy() function but it also copies the file metadata. So the destination file will have the same creation and modified date as the source file.
Here is its syntax.
shutil.copy(source, destination, *, follow_symlinks=True)
In this case, if follow_symlinks is false, and the source file is a symlink then the copy2() function will try to copy the source file metadata to destination symlink. But this feature is not available on all platforms. It will do its best to copy as much metadata as possible on the platform. If this is not supported, then it will copy file contents and leave it at that, without raising an Exception.
Using shutil.copyfileobj
shutil.copyfileobj() function is also useful for copying files. Here is its syntax.
shutil.copyfileobj(source, destination [, length])
In the above code, the first two arguments are for the source and destination file objects. The next argument is for the buffer length, for chunking. It allows you to copy file contents without overloading memory. Here is an example to copy file using this function.
shutil.copyfileobj('/home/ubuntu/data.txt', '/home/ubuntu/project.txt')
2. Using OS Module
OS module is a very comprehensive module that acts as an interface between Python and underlying OS. It provides tons of functions to easily interact with OS from any Python script, application or websites. It also provides a couple of functions to run system commands from within Python. They can be used for copying files using cp or mv function.
Using os.popen function
os.popen() function is a modern function that allows you to easily run system commands and capture their results. Here is its syntax.
os.popen(cmd[, mode[, bufsize]])
Here is an example to copy file from /home/ubuntu/data.txt to /home/ubuntu/project.txt.
## On Linux
os.popen('cp /home/ubuntu/data.txt /home/ubuntu/project.txt')
## On Windows
os.popen('copy /home/ubuntu/data.txt /home/ubuntu/project.txt')
Popen() function allows you to interact with standard input, output and errors. It also creates a new process to run the command and returns a handle that allows you to control the process as per your requirement. It is very useful to easily run cp and mv commands, since they allow you to quickly copy one or more files and directories from one location to another.
Here is an example to copy all files in /home/ubuntu to /home/projects folder.
## On Linux
os.popen('cp /home/ubuntu/* /home/projects')
## On Windows
os.popen('copy /home/ubuntu/* /home/projects')
Using os.system function
os.system() function allows you to run shell commands within a subshell. If the command returns any output it is sent to standard output. Here is its syntax.
os.system(command)
Here is an example to copy file using os.system() function.
os.system('cp /home/ubuntu/data.txt /home/ubuntu/project.txt')
It is not as sophisticated as popen() function but does the work. In fact, popen() function is built on os.system() function.
3. Using Subprocess Module
Subprocess is a powerful module that allows you to create and control system processes from within Python. You can also use it to connect to input/output/error pipes, and obtain return codes. It provides tons of functions for this purpose. You can also use this for running cp command.
Using subprocess.call
subprocess.call() function allows you to run system commands as arguments. Here is its syntax.
subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False)
The above command will run the system command mentioned in args, and return the returncode attribute. If you set shell=True, then it will spawn a new shell for the command. But please note, using shell=True can be a security risk and must be used only if necessary.
Here is an example to run cp command using call() function.
status = subprocess.call('cp /home/ubuntu/data.txt /home/project/data.txt', shell=True)
In the above case, we have passed the command as a single string. You can also pass a list of strings for this purpose, as shown below.
status = subprocess.call(['cp', '/home/ubuntu/data.txt', '/home/project/data.txt'], shell=True)
Using subprocess.check_output
subprocess.check_output() is another function that runs a command and returns the output, like call function. Here is its syntax.
subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, universal_newlines=False)
Here are the commands to copy files from one location to another.
## Linux/Unix
status = subprocess.check_output('cp /home/ubuntu/data.txt /home/ubuntu/project.txt', shell=True)
## Windows
status = subprocess.check_output('copy /home/ubuntu/data.txt /home/ubuntu/project.txt', shell=True)
Like in case of subprocess.call() function, you can pass the command argument as a string or as a list of strings.
# Linux/Unix
status = subprocess.check_output(['cp', '/home/ubuntu/data.txt', '/home/ubuntu/project.txt'], shell=True)
# Windows
status = subprocess.check_output(['copy', '/home/ubuntu/data.txt', '/home/ubuntu/project.txt'], shell=True)
Conclusion
In this article, we have learnt several simple ways to easily copy files and directories in Python. You can call these functions from a script, application or website. You can use them to copy a single file, multiple files or an entire directory from one place to another. Please make sure that the source file actually exists. Also ensure that the user that you are using has adequate read permission for source directory, and write permission in destination directory. You can use any of these functions as per your requirement.
Also read:
How to Iterate Over Rows in Pandas DataFrame
How to Iterate Over Dictionaries Using Loop
How to Find Index Of Given Item in Python List
Sreeram Sreenivasan is the Founder of Ubiq. He has helped many Fortune 500 companies in the areas of BI & software development.