- How to Recursively Copy a Folder (Directory) in Python
- Recursively Copying a Directory/Folder of Files in Python
- Copying Both Files and Directories in Python
- Ignoring Files and Directories
- About The Author
- Joey Payne
- Python COPY File and Directory Using shutil
- How to Copy Files in Python (shutil.copy())?
- Python shutil.copy() Syntax:
- Parameters:
- Python Program to Copy a File in Python
- How to Copy a File and Its Metadata in Python (shutil.copy2())?
- Python shutil.copy2() Syntax:
- Parameters:
- Python Program to Copy a File and Its Metadata in Python
- How to Copy a Directory in Python (shutil.copytree())?
- Python shutil.copytree() Syntax:
- Python Program to Copy a Directory in Python
- Conclusion
How to Recursively Copy a Folder (Directory) in Python
Ever tried to copy a directory/folder in Python? Ever failed? No matter. Try again!
If you haven’t already read it, look at the article How to Copy a File in Python with shutil for an explanation of how to copy files with shutil .
Recursively Copying a Directory/Folder of Files in Python
In the article that was mentioned above, we saw how to copy individual files in Python. I think you’ll agree that much more useful is the ability to copy entire directories into other directories.
Python’s shutil module once again saves our butts and has a function called copytree for doing just what we want.
We don’t need that drastic of a change, so I’ll modify our code above slightly to be able to copy directories as follows:
def copyDirectory(src, dest):
try:
shutil.copytree(src, dest)
# Directories are the same
except shutil.Error as e:
print(‘Directory not copied. Error: %s’ % e)
# Any error saying that the directory doesn’t exist
except OSError as e:
print(‘Directory not copied. Error: %s’ % e)
[/python]
Ok, nice! Almost the same as our function that copies single files, but it only allows to copy directories instead of files and the exceptions thrown are a bit different. Awesome.
Copying Both Files and Directories in Python
But what if we want one solid function that copies both files and directories? No problem! We can write a simple, slightly more complex function for that.
def copy(src, dest):
try:
shutil.copytree(src, dest)
except OSError as e:
# If the error was caused because the source wasn’t a directory
if e.errno == errno.ENOTDIR:
shutil.copy(src, dest)
else:
print(‘Directory not copied. Error: %s’ % e)
[/python]
This function will copy both files and directories. First, we put our copytree function in a try block to catch any nasty exceptions. If our exception was caused because the source directory/folder was actually a file, then we copy the file instead. Simple stuff.
A note to add is that it really isn’t possible to actually copy a directory over. You need to recursively walk the directories and create the directory structure based on the old one, and copy the files in each sub-directory to their proper directories at the destination. If you wished to implement this yourself, see this article for an example of how to recursively walk directories in Python.
Ignoring Files and Directories
The function shutil.copytree takes in an argument that allows you to specify a function that returns a list of directories or files that should be ignored.
A simple example function that does this is as follows:
[python]
def ignore_function(ignore):
def _ignore_(path, names):
ignored_names = []
if ignore in names:
ignored_names.append(ignore)
return set(ignored_names)
return _ignore_
[/python]
Alright, what does this function do? Well, we specify some sort of file or directory name as the argument ignore , which acts as the filter for names . If ignore is in names , then we add it to an ignored_names list that specifies to copytree which files or directories to skip.
How would we use this function? See our modified copy function below:
[python]def copy(src, dest):
try:
shutil.copytree(src, dest, ignore=ignore_function(‘specificfile.file’))
except OSError as e:
# If the error was caused because the source wasn’t a directory
if e.errno == errno.ENOTDIR:
shutil.copy(src, dest)
else:
print(‘Directory not copied. Error: %s’ % e)
[/python]
But what if we want to filter out more than just one file? Luckily, shutil has got us covered again! It’s got a function called shutil.ignore_patterns that allows us to specify glob patterns to filter out files and directories. See our once again modified copy function below:
[python]def copy(src, dest):
try:
shutil.copytree(src, dest, ignore=ignore_patterns(‘*.py’, ‘*.sh’, ‘specificfile.file’))
except OSError as e:
# If the error was caused because the source wasn’t a directory
if e.errno == errno.ENOTDIR:
shutil.copy(src, dest)
else:
print(‘Directory not copied. Error: %s’ % e)
[/python]
This will ignore all Python files, shell files and our own specific file when copying over the directory. ignore_patterns takes in arguments that specify the patterns to ignore and returns a function that copytree can understand, a lot like how our custom function ignore_function did it, but more robust.
That’s all I have to share with you!
About The Author
Joey Payne
I’m a python enthusiast that loves programming as a hobby. Entrepreneur in training, I’m working on cultivating sources of passive income in order to pursue the things I love to do.
Python COPY File and Directory Using shutil
Often developing a program , we need to manipulate the files and directories of the system. Let’s say we want to copy files and directories around different drivers or folders in a system. We can use the command prompt (in Windows) or terminal (on macOS and Linux) to copy a file from one location to another but what if we want to build a Python program that can do that for us!
Luckily Python comes with a standard module called shutil , which can help us to achieve this goal. Here in this Python tutorial, we will learn Python shutil module’s 3 methods; shutil.copy() , shutil.copy2() and shutil.copytree(). And by the end of this tutorial, you will know how to use these 3 shutil methods to copy files and directories from one location to another in Python.
How to Copy Files in Python (shutil.copy())?
Suppose you have a file in location x and you wish to copy that file to y location using Python. Here, you can use the Python shutil.copy() method.
Python shutil.copy() Syntax:
shutil.copy(source,destination)
Parameters:
The source parameter represents the source location of your file or the file you want to copy and it must be a string data type. The destination parameter represents the destination directory where the file should be copied and it should also be a string data type. The shutil.copy() method only copies the source file and paste it into the destination folder or directory.
Although the Python shutil.copy() method will copy the content of the source file to the destination folder it will not copy the file’s metadata. This means the metadata — like the created date and time of the file — will be not similar. The Return Value of shutil.copy() The shutil.copy() method returns the location for copied files in the string format.
Python Program to Copy a File in Python
Let’s say we have a file by name demo.txt at C:\Users\tsmehra\dev\example\ folder.
And we wish to copy the demo.txt file to D:\example2 folder.
#Python Program
import shutil source = r"C:\Users\tsmehra\dev\example\demo.txt" destination = r"D:\example2" print("The demo.txt has copied at:") print(shutil.copy(source, destination))
The demo.txt has copied at: D:\example2\demo.txt
Now check the D:\example2\ folder or directory
Here you can see that the demo.txt file of C:\Users\tsmehra\dev\example\ and demo.txt file of D:\example2\ has two different modified times . This is because the copy() method only copies the content and file, not the metadata. If you re-run the above program the shutil.copy() method will just overwrite the file.
: Always use raw string using r»» as a prefix for the source and destination to prevent the Python escape characters.
How to Copy a File and Its Metadata in Python (shutil.copy2())?
The Python shutil.copy() method only copies the file and its content to the destination folder, not metadata. But if you also wish to copy the metadata of the source file in the destination folder, you have to use the Python shutil.copy2() method.
Python shutil.copy2() Syntax:
shutil.copy2(source,destination)
Parameters:
The source parameter represents the source location of your file or the file you want to copy. It must be of string data type. The destination parameter represents the destination directory where the file should be copied. It should also be a string. The shutil.copy2() method not only copies the source file and paste it into the destination folder or directory, but also maintains similar metadata.
Python Program to Copy a File and Its Metadata in Python
Let’s take the same example but this time take a closer look at the metadata, such as the modified date and time for the source file and copied file. source file: C:\Users\tsmehra\dev\example\demo.txt
destination folder: D:\example2
#python program
import shutil source = r"C:\Users\tsmehra\dev\example\demo.txt" destination = r"D:\example2" print("The demo.txt has copied at:") print(shutil.copy2(source, destination))
The demo.txt has copied at: D:\example2\demo.txt
Now check the D:\example2\ folder or directory
Here you can see that the shutil.copy2() method not only copies the source file to the destination folder but the metadata, such as the modified date and time of the files is also the same.
How to Copy a Directory in Python (shutil.copytree())?
With shutil.copy() and shutil.copy2() methods you can copy a single source file to the destination folder but what if you want to copy a complete directory in python along with its files to a specific location.
To do this you can use the Python shutil.copytree() method. The copytree() method recursively copies all the files of the source directory and pastes into the destination directory.
Python shutil.copytree() Syntax:
shutil.copytree(source, destination, symlinks=False, ignore=None, copy_function=copy2, ignore_dangling_symlinks=False, dirs_exist_ok=False)
Parameters: The source represents the source directory that needs to copy and the destination parameter represents the location directory where the source directory shall be copied.
The dirs_exist_ok parameter is also very important. It signifies whether to raise an exception if the destination directory already exists or not. The default value of dirs_exist_ok is False . This means we can not copy the source directory to the existing directory.
We also need to specify a new directory where we want to copy all the files and folders of the source directory. If we set it to True , we can paste the source directory data into the existing directory.
Note: Apart from source and destination, all the other parameters are optional. Similar to the copy() and copy2() method, the copytree() method returns the destination directory.
Python Program to Copy a Directory in Python
source directory : C:\Users\tsmehra\dev\example
destination directory: D:\example2\copied_dir
#Python program to copy directory
import shutil source = r"C:\Users\tsmehra\dev\example" destination = r"D:\example2\copied_dir" print("The directory has copied at:") #this will create a new directory by name copied_dir print(shutil.copytree(source, destination))
The directory has copied at: D:\example2\copied_dir
Now let’s check the D:\example2\ directory again.
Here you can see that, the shutil.copytree() method creates a new directory with the name copied_dir and pastes all the data of C:\Users\tsmehra\dev\example into it. If we have specified the dirs_exist_ok=True , the example directory data will be copied to the example2 directory.
import shutil source = r"C:\Users\tsmehra\dev\example" destination = r"D:\example2" print("The directory has copied at:") print(shutil.copytree(source, destination, dirs_exist_ok=True))
Conclusion
In this Python tutorial, we learned how to write a Python program to copy a file, its metadata and an entire directory. You also learned the difference between shutil.copy() and shutil.copy2() .
With the shutil.copy() method, we can only copy the file and paste it to the destination. The shutil.copy2() method, however, not only copies the file but also maintains the metadata. Also, the shutil.copytree() method can copy the entire directory to the specified destination.
People are also reading: