Amir
Amir

Reputation: 496

Avoid duplicate file names in a folder in Python

I want to download some files and save them in a folder and there may be some duplication in file names, so I want to avoid this to happen. I think it needs an auto-naming system but now i don't know how to make it. I used shutil and urllib2 to write my function.

This is a part of my code :

path = 'C:/DL/Others/'+filename+file_ext
with open(path, 'wb') as fp:
    shutil.copyfileobj(req, fp)

As you know we can check that if a file exists or not by os.path.exists('path'). I wanna to rename my files and save them to avoid duplicated names using a pattern, for example by adding a number to file name.So if there was 4 files with same name, "fname", I want 4 files in this pattern : fname - fname(1) - fname(2) - fname(3)

Upvotes: 2

Views: 5783

Answers (2)

Daniel DiPaolo
Daniel DiPaolo

Reputation: 56390

Track each filename's count as you create it:

fname_counts = {}

# ... whatever generates filename and file_ext goes here...

if filename + file_ext in fname_counts:
     fname_counts[filename + file_ext] += 1
else:
     fname_counts[filename + file_ext] = 0


# now check if it's a dupe when you create the path
if fname_counts[filename + file_ext]:
     path = 'C:/DL/Others/%s_%s.%s' % (filename, fname_counts[filename + file_ext], file_ext)
else:
     path = 'C:/DL/Others/' + filename + file_ext 

Example at work with two duplicates ("test.txt"):

>>> filenames_and_exts = [('test', '.txt'), ('test', '.txt'), ('test2', '.txt'), ('test', '.cfg'), ('different_name', '.txt')]
>>> fname_counts = {}
>>> for filename, file_ext in filenames_and_exts:
    if filename + file_ext in fname_counts:
        fname_counts[filename + file_ext] += 1
    else:
        fname_counts[filename + file_ext] = 0
    if fname_counts[filename + file_ext]:
        path = 'C:/DL/Others/%s_%s%s' % (filename, fname_counts[filename + file_ext], file_ext)
    else:
        path = 'C:/DL/Others/' + filename + file_ext
    print path


C:/DL/Others/test.txt
C:/DL/Others/test_1.txt
C:/DL/Others/test2.txt
C:/DL/Others/test.cfg
C:/DL/Others/different_name.txt

Upvotes: 1

g.d.d.c
g.d.d.c

Reputation: 47978

Something like this is probably reasonable:

path = 'c:/DL/Others/%s%s' % (filename, file_ext)
uniq = 1
while os.path.exists(path):
  path = 'c:/DL/Others/%s_%d%s' % (filename, uniq, file_ext)
  uniq += 1

If the original path doesn't exist you get no _1, but if it does exist it'll count up until it finds one that's free.

Upvotes: 6

Related Questions