Home > OS >  Python 2.7 - copyfile errors file not found only on destination file
Python 2.7 - copyfile errors file not found only on destination file

Time:08-14

I'm trying to copy files from source to destination. The file is there in the source location. The exception is raised on the destination file. Specifically, the try: os.close(fout) line. The traceback.print_exc() is UnboundLocalError: local variable 'fout' referenced before assignment.

fout is assigned prior to that line, fout = os.open(dst, WRITE_FLAGS, stat.st_mode). It appears to only throw the exception on certain files. I've been away from python for a little bit now. Not really understanding why the exception is being thrown. I believe fout is not opening/creating the file. But why no exception at fout = os.open(dst, WRITE_FLAGS, stat.st_mode) or during the write os.write(fout, x). Any help to point me in the write direction is greatly appreciated.

Original copyfile code is from this thread How to Copy Files Fast.

import os
import traceback

class CTError(Exception):
    def __init__(self, errors):
        self.errors = errors

try:
    O_BINARY = os.O_BINARY
except:
    O_BINARY = 0
READ_FLAGS = os.O_RDONLY | O_BINARY
WRITE_FLAGS = os.O_WRONLY | os.O_CREAT | os.O_TRUNC | O_BINARY
BUFFER_SIZE = 128*1024

def copyfile(src, dst):
    try:
        fin = os.open(src, READ_FLAGS)
        stat = os.fstat(fin)
        fout = os.open(dst, WRITE_FLAGS, stat.st_mode)
        for x in iter(lambda: os.read(fin, BUFFER_SIZE), ""):
            os.write(fout, x)
    finally:
        try: os.close(fin)
        except:
            #fin2 = open("C:\\Users\\testUser\\ScriptErrLogs\\saveErrors.txt", 'a ')
            #fin2.write(traceback.print_exc())
            #fin2.close()
            pass
        try: os.close(fout)
        except:
            fin2 = open("C:\\Users\\testUser\\ScriptErrLogs\\saveErrors.txt", 'a ')
            e = str(traceback.print_exc())
            fin2.write(e)
            fin2.close()
            print os.path.isfile(src)
            print os.path.isfile(dst) 
            pass 


DEBUG = 1

f = open('C:\\Users\\testUser\\Scripts\\Python\\testImport.csv','r')
lines = f.readlines()

for line in lines:
    temp = line.split('\\')
    tempFileName = line[0:-1]
    tempPath = 'C:\\Users\\testUser\\testSaveLocation\\testSave'

    # DEBUG prints
    if DEBUG == 0:
        print '#### LINE ####'
        print line
        print '#### FILENAME ####'
        print tempFileName

    # Discard the first 3 elements to create the new location path
    for entry in temp[3:]:
        tempPath = tempPath   '\\'  entry

        # DEBUG prints
        if DEBUG == 0:
            print '#### TEMPPATH ####'
            print tempPath

        # Check path exists
        pathExists = os.path.exists(tempPath)

        # Create directory structure
        if not pathExists and not '.pdf' in entry:
            try:
                os.mkdir(tempPath)
            except OSError as error:
                print error

        # Copy file to new location
        if '.pdf' in entry:
            try:
                copyfile(line[:-1],tempPath[:-1])
            except OSError as error:
                print error

CodePudding user response:

Looks to me like fout is being assigned inside a try block, and used inside a finally block. Maybe your code is excepting out before fout gets assigned. One easy fix, perhaps: set fout = None before the try, and only perform the close if fout is not None (and to be safe, you may want to protect fin the same way).

To debug why you're excepting out early, you can catch the exception and print it out:

...
def copyfile(src, dst):
    fin = None
    fout = None
    try:
        fin = os.open(src, READ_FLAGS)
        stat = os.fstat(fin)
        fout = os.open(dst, WRITE_FLAGS, stat.st_mode)
        for x in iter(lambda: os.read(fin, BUFFER_SIZE), ""):
            os.write(fout, x)
    except Exception as e:
        print e
    finally:
        ...

Once you figure out what's going on, you should be able to handle the error case in the try block, or before you perform the excepting operation.

CodePudding user response:

Turns out this is not a FileNotFoundError or a UnboundLocalError issue, its a path length issue.

fin opens without issue but when assigning fout, in my case, the path length is too long. Manually typing the statement fails at the original fout assignment. I'm trying to preserve the path of the original file, just stored in a different root folder. It occurred to me that it maybe a path length issue, looking at the original path. I shortened the path to the destination and the copy worked.

Prepending \\\\?\\ to tempPath resolved the issue. All files copied without issue. For local drives, \\\\?\\c:\\ resolved the issue. For network shares, \\\\?\\server\\share would resolve the issue for me as well.

  • Related