How to deal with OSError: [Errno 20] Not a directory: '.DS_Store'?

31.4k views Asked by At

I want to copy some pictures from on directory to another directory, and here is my code:

import os.path
import shutil

def copyFile(sourceDir,targetDir):
    for files in os.listdir(sourceDir):
        sourceFile=os.path.join(sourceDir,files)
        if os.path.isfile(sourceFile) and sourceFile.find('.jpg')>0:
            shutil.copy(sourceFile,targetDir) 

for i in os.listdir('/Users/liuchong/Desktop/LFW/new'):

    copyFile(i,'/Users/liuchong/Desktop/LFW/lfw')  

But when I run it ,the terminal tells me thatOSError: [Errno 20] Not a directory: '.DS_Store' I know 'DS_dstore' is a hidden file in Mac, but how can I solve this bug?

4

There are 4 answers

1
Daniel Roseman On BEST ANSWER

Your logic seems badly broken. You iterate through all the files in the directory, passing each one to copyFile. But inside that function, you again try to iterate through each file in the "directory" passed to the function: except that you're not passing only directories to the function, you're passing each file found in the original directory.

It's not clear what you are trying to do, but I think you need to remove one of those calls to listdir and the associated loop.

2
franklinsijo On

When you do os.listdir('/Users/liuchong/Desktop/LFW/lfw'), it returns both directories and files. You have to check the entry for directory before passing it as an argument.

def copyFile(sourceDir,targetDir):
    for files in os.listdir(sourceDir):
        sourceFile=os.path.join(sourceDir,files)
        if os.path.isfile(sourceFile) and sourceFile.find('.jpg')>0:
            shutil.copy(sourceFile,targetDir)

for i in os.listdir('/Users/liuchong/Desktop/LFW/lfw'):
     if os.path.isdir(i):
         i = os.path.join( '/Users/liuchong/Desktop/LFW/lfw', i)
         copyFile(i,'/Users/liuchong/Desktop/LFW/lfw')
0
Alexander Samoylov On

It is worth to mention what is the general meaning of the "Not a directory" error (Errno 20). It means that you are trying to operate with a path which sub-path is a real file and not a directory. That is it is a malformed, incorrect path.

Example: file.txt/test.txt where file.txt is an existing true file (not a directory).

Python will return this error for every I/O operation with such a file:

$ python -c 'import os; os.path.getsize("file.txt/test.txt");'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib/python2.7/genericpath.py", line 57, in getsize
    return os.stat(filename).st_size
OSError: [Errno 20] Not a directory: 'file.txt/test.txt'

The OS will also return this error:

$ stat file.txt/test.txt
stat: cannot stat 'file.txt/test.txt': Not a directory

Every time you have this error it means that you concatenate file+file somewhere in your program.

This error is Unix OS specific. On Windows you should get "File not found" for such malformed path.

0
WaterRocket8236 On
os.listdir('/Users/liuchong/Desktop/LFW/lfw')

returns a list which contains the names of entries in the directory that is given by the user. List is based on random choices.

To address this issue (I know I am late) here's a python 3 compatible code:-

import time
import os
from shutil import copyfile

def Copyfile(in_path, out_path, quantity = None):

    filelist = os.listdir(in_path)
    counter = 0
    print("Copying to %r directory. Please wait... " % out_path)

    start = time.time()

    for i in range(quantity):
        copyfile(filelist[i], out_path+filelist[i])
        counter+=1
        sys.stdout.write("\rTotal images copied : %r" % counter)
        sys.stdout.flush()   

    end = time.time()
    print("This move operation took %r seconds to run." %(end - start))