-1

Here is my code for replacing all the occurrences of kyle and john with mike and jim respectively.

import os
import fileinput
import sys


rootdir ='C:/Users/sid/Desktop/app'
searchTerms={"kyle":"mike","john":"jim"}

def replaceAll(file,searchExp,replaceExp):
    for line in fileinput.input(file, inplace=1):
        if searchExp in line:
            line = line.replace(searchExp,replaceExp)
        sys.stdout.write(line)

for subdir, dirs, files in os.walk(rootdir):
    for file in files:
            path=subdir+'/'+file
            for key,value in searchTerms.items():
                replaceAll(path,key,value)

This was working fine for a test directory i created. When i changed the rootdir to my actual java project directory, I was getting

Traceback (most recent call last):
  File "C:\Users\sid\Desktop\test_iterator.py", line 19, in <module>
    replaceAll(path,key,value)
  File "C:\Users\sid\Desktop\test_iterator.py", line 10, in replaceAll
    for line in fileinput.input(file, inplace=1):
  File "C:\Python33\lib\fileinput.py", line 261, in __next__
    line = self.readline()
  File "C:\Python33\lib\fileinput.py", line 330, in readline
    os.rename(self._filename, self._backupfilename)
FileExistsError: [WinError 183] Cannot create a file when that file already exists: 'C:/Users/sid/Desktop/app/pom.template.xml.bak'         

Can someone please explain why im getting this error. I have read the post about os.rename() FileExistsError but i couldnot understand it. Can some please explain in detail.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Wolf
  • 3,019
  • 3
  • 17
  • 14

1 Answers1

2

When you use fileinput.input(..., inplace=1), the input file is renamed, and any output your code produces on sys.stdout is written to a newly created file with the original filename.

fileinput thus has to rename the original file first, by adding .bak to the name. However, it appears there already is such a file present. Probably you had a bug in your code before and the backup file was never deleted.

Verify that C:/Users/sid/Desktop/app/pom.template.xml.bak does not contain anything you want to keep, then delete it or move it back to C:/Users/sid/Desktop/app/pom.template.xml.

If, however, you keep running into this then Python has problems deleting the backup files automatically. On Windows this is usually because another process keeps opening files for their own purposes in the background. You could try deleting the backup file after a timeout:

import time, os

def replaceAll(file,searchExp,replaceExp):
    for line in fileinput.input(file, inplace=1):
        if searchExp in line:
            line = line.replace(searchExp,replaceExp)
        sys.stdout.write(line)

    time.sleep(1) # wait 1 second, then delete the backup
    os.remove(file + '.bak')

If your files are read-only, make them writable first:

import os, stat

def replaceAll(file,searchExp,replaceExp):
    readonly = not os.stat(myFile)[0] & stat.S_IWRITE
    if readonly:
        os.chmod(file, stat.S_IWRITE)

    for line in fileinput.input(file, inplace=1):
        if searchExp in line:
            line = line.replace(searchExp,replaceExp)
        sys.stdout.write(line)

    if readonly:
        os.chmod(file, stat.S_IREAD)
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • i have deleted the pom.template.xml.bak file and when i execute the code again the same error is coming – Wolf Oct 28 '13 at 13:22
  • Interesting; that would only happen if the backup file cannot be deleted; `fileinput` explicitly tries to delete any existing backup file first. Do you have some kind of process that automatically backs up files or otherwise briefly opens files in the background? On Windows that would lock a file against deletion. – Martijn Pieters Oct 28 '13 at 13:29
  • im sorry, all my files are read-only files. When i changed them by right clicking on the file and removing the read-only check box, it was working fine. Is there an option to convert a file to read-only in python – Wolf Oct 28 '13 at 13:34