how to copy directory with all file from c:\xxxyyy to c:\zzz in python

Question:

I’ve been trying to use “copytree(src,dst)”, however I couldn’t since the destination folder should exists at all.Here you can see the small piece of code I wrote:

def copy_dir(src,dest):
    import shutil
    shutil.copytree(src,dest)

copy_dir('C:/crap/chrome/','C:/test/') 

and this is the error I m getting as I expected…

Traceback (most recent call last):
File "C:Documents and SettingsAdministratorworkspaceMMS-Autocopy.py", line 5, in        <module>
copy_dir('C:/crap/chrome/','C:/test/')   
File "C:Documents and SettingsAdministratorworkspaceMMS-Autocopy.py", line 3, in copy_dir
shutil.copytree(src,dest)
File "C:Python27libshutil.py", line 174, in copytree
os.makedirs(dst)
File "C:Python27libos.py", line 157, in makedirs
mkdir(name, mode)
WindowsError: [Error 183] Cannot create a file when that file already exists:    'C:/test/'

Here is my question is there a way I could achieve the same result without creating my own copytree function?

Thank you in advance.

Asked By: nassio

||

Answers:

I’m pretty sure this depends on the exact version of python you have, but when i call shutil.copytree.doc i get this:

Recursively copy a directory tree using copy2().

The destination directory must not already exist.

XXX Consider this example code rather than the ultimate tool.

This explains the error you are getting. You could probably use distutils.dir_util.copy_tree instead.

Answered By: marue

Look at errno for possible errors. You can use .copytree() first, and then when there is error, use shutil.copy.

From: http://docs.python.org/library/shutil.html#shutil.copytree

If exception(s) occur, an Error is raised with a list of reasons.

So then you can decide what to do with it and implement your code to handle it.

import shutil, errno

def copyFile(src, dst):
    try:
        shutil.copytree(src, dst)
    # Depend what you need here to catch the problem
    except OSError as exc: 
        # File already exist
        if exc.errno == errno.EEXIST:
            shutil.copy(src, dst)
        # The dirtory does not exist
        if exc.errno == errno.ENOENT:
            shutil.copy(src, dst)
        else:
            raise

About .copy(): http://docs.python.org/library/shutil.html#shutil.copy

Copy the file src to the file or directory dst. If dst is a directory,
a file with the same basename as src is created (or overwritten) in
the directory specified. Permission bits are copied. src and dst are
path names given as strings.

Edit: Maybe also look into distutils.dir_util.copy_tree

Answered By: George

I have a little work around that check whether there is a directory of the same name in the location first before doing the shutil.copytree function. Also it only copies directories with a certain wildcard. Not sure if that is needed to answer the question but I thought to leave it in there.

import sys
import os
import os.path
import shutil 


src="/Volumes/VoigtKampff/Temp/_Jonatha/itmsp_source/"
dst="/Volumes/VoigtKampff/Temp/_Jonatha/itmsp_drop/"


for root, dirs, files in os.walk(src):
    for dir in dirs:
        if dir.endswith('folder'):
            print "directory to be moved: %s" % dir
            s = os.path.join(src, dir)
            d = os.path.join(dst, dir)
            if os.path.isdir(d):
                print "Not copying - because %s is already in %s" % (dir, dst)
            elif not os.path.isdir(d):
                shutil.copytree(s, d)
                print "Copying %s to %s" % (dir, dst)
Answered By: JRM

Notice:

distutils has been deprecated and will be removed in Python 3.12. Consider looking for other answers at this question if you are looking for a post-3.12 solution.


Original answer:

I used the distutils package to greater success than the other answers here.

http://docs.python.org/2/distutils/apiref.html#module-distutils.dir_util

The distutils.dir_util.copy_tree function works very similarly to shutil.copytree except that dir_util.copy_tree will just overwrite a directory that exists instead of crashing with an Exception.

Replace:

import shutil
shutil.copytree(src, dst)

with:

import distutils.dir_util
distutils.dir_util.copy_tree(src, dst)
Answered By: Nick Pickering
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.