Search code examples
pythonfile-copying

Why is my python script unable to copy a file which definitely exists?


Source code:

import os
import shutil
import errno
from pathlib import Path

def copyFile(src, dst, buffer_size=10485760, perserveFileDate=True):
    '''
    Copies a file to a new location. Much faster performance than Apache Commons due to use of larger buffer
    @param src:    Source File
    @param dst:    Destination File (not file path)
    @param buffer_size:    Buffer size to use during copy
    @param perserveFileDate:    Preserve the original file date
    '''
    #    Check to make sure destination directory exists. If it doesn't create the directory
    dstParent, dstFileName = os.path.split(dst)
    if(not(os.path.exists(dstParent))):
        os.makedirs(dstParent)
   
    #    Optimize the buffer for small files
    buffer_size = min(buffer_size,os.path.getsize(src))
    if(buffer_size == 0):
        buffer_size = 1024
   
    if shutil._samefile(src, dst):
        raise shutil.Error("`%s` and `%s` are the same file" % (src, dst))
    for fn in [src, dst]:
        try:
            st = os.stat(fn)
        except OSError:
            # File most likely does not exist
            pass
        else:
            # X X X What about other special files? (sockets, devices...)
            if shutil.stat.S_ISFIFO(st.st_mode):
                raise shutil.SpecialFileError("`%s` is a named pipe" % fn)
    with open(src, 'rb') as fsrc:
        with open(dst, 'wb') as fdst:
            shutil.copyfileobj(fsrc, fdst, buffer_size)
   
    if(perserveFileDate):
        shutil.copystat(src, dst)


pdb_dir_str = "/mnt/storage/DATABASES/PDB_MIRROR/wwpdb"


if __name__ == "__main__":  
    full_file_name_str = Path(pdb_dir_str, "pdb1a6j.ent.gz")
    print(full_file_name_str)
    copyFile(full_file_name_str, "new_file.zip")

Output:

user_name@server_name:~/kfc_spatial/kfc_pdb_list$ ls /mnt/storage/DATABASES/PDB_MIRROR/wwpdb/pdb1a6j.ent.gz
/mnt/storage/DATABASES/PDB_MIRROR/wwpdb/pdb1a6j.ent.gz
user_name@server_name:~/kfc_spatial/kfc_pdb_list$ nano *.py
user_name@server_name:~/kfc_spatial/kfc_pdb_list$ python3 file_copy.py
/mnt/storage/DATABASES/PDB_MIRROR/wwpdb/pdb1a6j.ent.gz
Traceback (most recent call last):
  File "file_copy.py", line 70, in <module>
    copyFile(full_file_name_str, "new_file.zip")
  File "file_copy.py", line 18, in copyFile
    os.makedirs(dstParent)
  File "/usr/local/lib/python3.7/os.py", line 221, in makedirs
    mkdir(name, mode)
FileNotFoundError: [Errno 2] No such file or directory: ''
user_name@server_name:~/kfc_spatial/kfc_pdb_list$

Debug:

Python 3.7.3 (default, Jul 23 2019, 01:21:07)
[GCC 5.5.0 20171010] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.path.split("pdb1a6j.ent.gz")
('', 'pdb1a6j.ent.gz')
>>>

Why is my python script unable to copy a file which definitely exists?


Solution

  • It has nothing to do with the input file. The stack trace indicates that the error is happening in mkdir(). I believe that since you are passing a simple filename as the destination to copyFile(), then dstParent will be an empty string which causes os.makedirs() to throw this error.