I want to copy a file like for example Ubuntu Nautilus file manager does. If destination already exists it creates new filename with larger index. I tried shutil.copyfile but it overwrites destination file. How to increment filename if destination file already exists in python?
shutil.copyfile(src, dst, *, follow_symlinks=True)¶
Copy the contents (no metadata) of the file named src to a file named dst and return dst. src and dstare path names given as strings. dst must be the complete target file name; look at shutil.copy() for a copy that accepts a target directory path. If src and dst specify the same file, SameFileError is raised.
The destination location must be writable; otherwise, an OSError exception will be raised. If dst already exists, it will be replaced. Special files such as character or block devices and pipes cannot be copied with this function.
If follow_symlinks is false and src is a symbolic link, a new symbolic link will be created instead of copying the file src points to.
Changed in version 3.3: IOError used to be raised instead of OSError. Added follow_symlinks argument. Now returns dst.
Changed in version 3.4: Raise SameFileErrorinstead of Error. Since the former is a subclass of the latter, this change is backward compatible.
exception shutil.SameFileError
This exception is raised if source and destination in copyfile() are the same file.
Related
So I'm moving a lot of files within folders to the layer above all the folders. Essentially what I need to happen is if a file was removed from a folder (to the layer above), then delete the folder it was removed from. Something like:
for file in files:
print(file)
shutil.move(file, downloads_path)
moved = shutil.move(file, downloads_path)
if moved is True:
os.remove(downloads_folder_path)
shutil.move will return you a string of the new file name if successful and raise an Exception if either the source or the target wasn't found.
So actually there is no need to check for its return value at all. You can just proceed with moving everything and then delete the original folder.
I am trying to copy a word file from an existing folder and copying it to a new output folder. In this output folder, I have again created different folders as per the user id and inside this the word file should be placed for every user. However, while copying this, I am facing an issue as the id folder is interpreted as
a file. The output file picture is attached here:
I am using the shutil module for this and the code which I wrote is:
id = tup2[i]
shutil.copy('C:\\Python27\\mydoc.docx', ('C:\\Python27\\Output\\%s') %(id))
that's expected. If the destination folder exists, then copy appends the basename of your file and copies the file into the destination folder.
Copies the file src to the file or directory dst. src and dst should be strings. If dst specifies a directory, the file will be copied into dst using the base filename from src.
If it doesn't, then copy assumes that you want to copy and change the name (the unix cp commands works exactly the same).
A workaround would be to create the directory beforehand/ensure it's here:
import os,shutil
output_dir = os.path.join(r'C:\Python27\Output',str(id))
if not os.path.isdir(output_dir):
os.mkdir(output_dir)
shutil.copy(r'C:\Python27\mydoc.docx', output_dir)
(it's also better to use proper path handling functions from os.path and raw strings for litteral windows paths)
This question already has answers here:
How to copy files
(25 answers)
Closed 5 years ago.
I have the path of a file stored in a variable (say) filePath. I would like to copy that particular file to another specific folder within a Python script.
I tried
folderPath = (os.getcwd() + "/folder_name/") #to get the path of the folder
shutil.copyfile(filePath, folderPath)
But I got an error IOError: [Errno 21] Is a directory.
How can I solve this ?
My question might seem to be a duplicate of How do I copy a file in python?
. But actually, I want to copy a file to a folder/directory whereas most answers to that question mention copying one file to another file.
Use shutil.copy(filePath, folderPath) instead of shutil.copyfile(). This will allow you to specify a folder as the destination and copies the file including permissions.
shutil.copy(src, dst, *, follow_symlinks=True):
Copies the file src to the file or directory dst. src and dst should be strings. If dst specifies a directory, the file will be copied into dst using the base filename from src. Returns the path to the newly created file.
...
copy() copies the file data and the file’s permission mode (see os.chmod()). Other metadata, like the file’s creation and modification times, is not preserved. To preserve all file metadata from the original, use copy2() instead.
https://docs.python.org/3/library/shutil.html#shutil.copy
See the difference in copying also documented in shutil.copyfile() itself:
shutil.copyfile(src, dst, *, follow_symlinks=True):
Copy the contents (no metadata) of the file named src to a file named dst and return dst. src and dst are path names given as strings. dst must be the complete target file name; look at shutil.copy() for a copy that accepts a target directory path. If src and dst specify the same file, SameFileError is raised.
https://docs.python.org/3/library/shutil.html#shutil.copyfile
folderpath must be a file, not a directory. The error says it all. Do something like:
shutil.copyfile(filePath, folderPath+'/file_copy.extension')
Change your code as below:
folderPath = os.path.join('folder_name', os.path.basename(filePath))
shutil.copyfile(filePath, folderPath)
I'm trying to replace a file in a zipped archive with a script using zipfile. The file is one directory, the archive is in another. To do this, I copy everything from the original archive into another, excluding the file I want to replace. Then I write the new version of the file to replace into the new archive, close it, and delete the old archive and rename the new one. Should be easy, right? Wrong.
For whatever reason, the zipfile.write() method has this silly thing it does where it assumes that the second (optional) argument, arcname is the same as your file name, unless you specify it. So, if I have the following:
fileName = "C:\\Documents\\file"
archive.write(fileName)
I will get an archive with a subarchive called "Documents", and within that will be the file. I want the file to be in the root directory of the archive (sidenote: is 'root directory' the right term for what I'm refering to?)
Thing's I've Tried:
archive.write(fileName,'') This produced a weird file in the archive, which could not be opened.
archive.write(fileName, archive) I really thought this would work, but the system really didn't like it.
archive.write(fileNameWithoutPath) This one returned an error, since Python could no longer find the file.
So how do I specify that I want to put the file in the root directory of the archive and still specify its path so Python can find it?
Minor, and semi-related question: Is there a way to create the new archive such that it is hidden in windows explorer?
I am assuming you want a entry in the zipfile called file containin the contents of C:\Documents\file
From python docs
ZipFile.write(filename[, arcname[, compress_type]])
Write the file named filename to the archive, giving it the archive name arcname
so you want
archive.write(fileName, fileNameWithoutPath)
The first argument is the file that goes in the zip and the second is the name that is to be used in the archive, as it contains no path separators it will not create any directories.
As tempfile.mktemp is depreciated in Python 2.7 I generate a unique path to a temporary file as follows:
temp = tempfile.NamedTemporaryFile(suffix=".py")
path_to_generated_py = temp.name
temp.close()
# now I use path_to_gerated_py to create a python file
Is this the recommended way in Python 2.7? As I close the temp file immediately it looks like misusing NamedTemporaryFile....
The direct replacement for tempfile.mktemp() is tempfile.mkstemp(). The latter creates the file, like NamedTemporaryFile, so you must close it (as in your code snippet). The difference with NamedTemporaryFile is that the file is not deleted when closed. This is actually required: your version has a theoretical race condition where two processes might end up with the same temporary file name. If you use mkstemp() instead, the file is never deleted, and will likely be overwritten by the 3rd-party library you use --- but at any point in time, the file exists, and so there is no risk that another process would create a temporary file of the same name.