-2

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?

user366312
  • 16,949
  • 65
  • 235
  • 452
  • 2
    the error message implies you are passing an empty string... – juanpa.arrivillaga Oct 20 '22 at 16:46
  • 3
    So, did you **look** at what `os.path.split("pdb1a6j.ent.gz")` returns? Any debugging at all? – juanpa.arrivillaga Oct 20 '22 at 16:47
  • 1
    You're clearly not debugging your script as you go along. There's no excuse for not doing this basic task which you should've learned from day 1, let alone in 2022. PyCharm is free and has an excellent debugger: https://www.jetbrains.com/help/pycharm/debugging-your-first-python-application.html Not debugging your code is like building and designing an airplane from scratch without testing or planning and just hoping it flies. – Random Davis Oct 20 '22 at 16:51
  • 2
    It's not telling you that it can't read the file. It's telling you that it cannot create a directory whose name is the empty string (`''`). – rici Oct 20 '22 at 16:56
  • read the error message, then look at what you pasted from debugging... clearly `dstParent` is an empty string, so it seems your problem is `if(not(os.path.exists(dstParent)))` is `True` because the code then attempts `os.makedirs(dstParent)` which fails. So you need something like `if dstParent and not(os.path.exists(dstParent)):` instead. – Anentropic Oct 20 '22 at 16:57
  • `dstParent` is empty string so `os.makedirs(dstParent)` throws error cuz there's no dir to make. How about you check if it's not empty `if(dstParent != "" and not(os.path.exists(dstParent))):` – Combinacijus Oct 20 '22 at 16:57

2 Answers2

3

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.

Dave Costa
  • 47,262
  • 8
  • 56
  • 72
0

I add check condition for empty string above os.makedirs. If the directory is a "" empty string then a Exception will be raise.

import os
import shutil
import errno
from pathlib import Path
import

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(dstParent == ""):
        raise Exception("directory string is empty")

    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")
rafathasan
  • 524
  • 3
  • 15