I am trying to copy files on Windows with Python 2.7, but sometimes this fails.
shutil.copyfile(copy_file, dest_file)
I get the following IOError:
[Errno 2] No such file or directory
But the file does exist! The problem is that the path of the file is too long. (> 255 characters)
How do I copy these files? It isn't a problem to open them in other applications.
To create a file with a too long path, create a file with an as long as possible file name and move the containing folder deeper down a tree structure.
I've been trying some of these methods without success: http://timgolden.me.uk/python/win32_how_do_i/copy-a-file.html
(if the path is too long) First copy the folder to upper levels in windows explorer and then move it to your local computer. (if file names are too long) First try to zip/rar/7z them with an archive application and then copy the archive file to your local computer and then extract the contents. Use third party apps.
Windows has a limitation where the entire path to a file cannot be over 255 characters. Microsoft has a command line copy program called "Robocopy" (Robust Copy) that can copy files without this limitation. ROBOCOPY will accept UNC pathnames including UNC pathnames over 256 characters long.
To do this, use one of the following methods: Rename the file so that it has a shorter name. Rename one or more folders that contain the file so that they have shorter names. Move the file to a folder with a shorter path name.
I wasn't sure about the 255 char limit so I stumbled on this post. There I found a working answer: adding \\?\ before the path.
shutil.copyfile("\\\\?\\" + copy_file, dest_file)
edit: I've found that working with long paths causes issues on Windows. Another trick I use is to just shorten the paths:
import win32api
path = win32api.GetShortPathName(path)
Thanks for the answer Gfy. I have a requirement to use relative paths. The \\?\
can't be added successfully to a relative path, so it's necessary to convert to an absolute path first (run from desktop):
import os
def clean_path(path):
path = path.replace('/',os.sep).replace('\\',os.sep)
if os.sep == '\\' and '\\\\?\\' not in path:
# fix for Windows 260 char limit
relative_levels = len([directory for directory in path.split(os.sep) if directory == '..'])
cwd = [directory for directory in os.getcwd().split(os.sep)] if ':' not in path else []
path = '\\\\?\\' + os.sep.join(cwd[:len(cwd)-relative_levels]\
+ [directory for directory in path.split(os.sep) if directory!=''][relative_levels:])
return path
clean_path('samples')
\\?\C:\Users\Username\Desktop\samples
clean_path('\samples')
\\?\C:\Users\Username\Desktop\samples
clean_path('..\samples')
\\?\C:\Users\Username\samples
clean_path('..\..\samples')
\\?\C:\Users\samples
clean_path('C:\Users\Username\Dropbox')
\\?\C:\Users\Username\Dropbox
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With