Reputation: 2291
I have made a Python program which will clean up the unnecessary names present in my downloaded torrent files+folders, so that I can upload it to my unlimited Google Drive Storage Account without much hassle.
However, it gives me the: WindowsError: [Error 2] The system cannot find the file specified
after certain number of iterations.If I run the program again, it works fine for a certain iterations and then the same error pops up.
Note that I have taken precautions using os.path.join
to avoid this error but it keeps coming up. Because of this error, I have to run the program tens of times over a selected folder/drive.
Here is my program:
import os
terms = ("-LOL[ettv]" #Other terms removed
)
#print terms[0]
p = "E:\TV Series"
for (path,dir,files) in os.walk(p):
for name in terms:
for i in files:
if name in i:
print i
fn,_,sn = i.rpartition(name)
os.rename(os.path.join(path, i), os.path.join(path, fn+sn))
for i in dir:
if name in i:
print i
fn,_,sn = i.rpartition(name)
os.rename(os.path.join(path, i), os.path.join(path, fn+sn))
And the Error Traceback:
Traceback (most recent call last):
File "E:\abcd.py", line 22, in <module>
os.rename(os.path.join(path, i), os.path.join(path, fn+sn))
WindowsError: [Error 2] The system cannot find the file specified
Upvotes: 3
Views: 1670
Reputation: 6341
Probably it's the problem with subdirectories due to the way os.walk
works, namely path
on next iteration after the first with subdirectories. os.walk
gathers subdirectories' names to visit on further iterations on it's first iteration in current directory...
E.g., on first call to os.walk
you get:
('.', ['dir1', 'dir2'], ['file1', 'file2'])
now you rename the files (this works ok), and you rename: 'dir1'
to 'dirA'
and 'dir2'
to 'dirB'
.
On next iteration of os.walk
, you get:
('dir1', ['subdir1-2', 'subdir1-2'], ['file1-1', 'file1-2'])
And what happens here is there's no 'dir1'
anymore, as it is already renamed on the file system, but os.walk
still remembers it's old name in the list inside and gives it to you. Now, when you try to rename 'file1-1'
you ask for 'dir1/file1-1'
, but on the file system it's actually is 'dirA/file1-1'
and you get the error.
To solve this issue, you need to change the values in the list that is used by os.walk
on further iterations, e.g. in your code:
for (path, dir, files) in os.walk(p):
for name in terms:
for i in files:
if name in i:
print i
fn, _, sn = i.rpartition(name)
os.rename(os.path.join(path, i), os.path.join(path, fn+sn))
for i in dir:
if name in i:
print i
fn, _, sn = i.rpartition(name)
os.rename(os.path.join(path, i), os.path.join(path, fn+sn))
#here remove the old name and put a new name in the list
#this will break the order of subdirs, but it doesn't
#break the general algorithm, though if you need to keep
#the order use '.index()' and '.insert()'.
dirs.remove(i)
dirs.append(fn+sn)
This should do the trick and in described above scenario, will lead to...
On first call to os.walk
:
('.', ['dir1', 'dir2'], ['file1', 'file2'])
now rename: 'dir1'
to 'dirA'
and 'dir2'
to 'dirB'
and change the list as shown above... Now, on next iteration of os.walk
it should be:
('dirA', ['subdir1-2', 'subdir1-2'], ['file1-1', 'file1-2'])
Upvotes: 3