Search code examples
javafilebufferedreaderfilereaderioexception

How to replace a word in an exisiting text file in java


I want to replace a word to another word in an existing text file. I think my code is correct but whenever I run the program all the text gets deleted in the text file.

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Test {
    public static void main(String ar[]) throws IOException{

         String getText, putText;
         File f = new File("Test.txt");
         FileReader fr ;
         BufferedReader br ;
         BufferedWriter bw;
         if(f.exists()){
             try{
                 fr = new FileReader(f);
                 br = new BufferedReader(fr);
                 bw = new BufferedWriter(new FileWriter(f));
                 while((getText = br.readLine()) != null){
                     System.out.println(getText);
                     if(getText != null){
                         putText = getText.replaceFirst("Dog", "Cat");
                         bw.write(putText);
                     }   
                 }
                bw.close();
                br.close();
             }
             catch(IOException e){
                 e.printStackTrace();
             }
         }else{
             System.out.println("No File exists!");
         }
    }
}

Solution

  • You simply should not read and write from/to the same file at the same point in time.

    Instead: read from file A; and write to some file A.tmp.

    And if you absolutely want to, you can still delete A, and rename A.tmp to A in the end.

    Finally, just for the record: if your goal is really just that; to replace some strings in some text file, the more reasonable answer would be to look into tools such sed (or some alternatives that exist for Windows OSes).

    To replace only the first occurance of some string, you have to add some marker that tells you if you replaced already, like:

    boolean replacingRequired = true;
    while ( ... reading ...) 
      if (replacingRequired) {
         putText = getText.replaceFirst("Dog", "Cat")
         if (! putText.equals(getText)) {
           // when they are different, you replaced something!
           replacingRequired = false;
         }
      ...
    

    Final finally: as you are now asking about replacing the last occurance ... well, that is a completely different and harder problem. You see, your current approach is to read that input file line by line, update that line, and write that to the new file. But: how could code that goes line-by-line know that this line ... is the last one that carries the pattern that you wish to replace?! Short answer: it can't.

    The simply solution here; which works nicely unless your files are really big:

    1. Read all lines into a List of strings (using this method for example)
    2. Then walk backwards through that list; and replace the first occurrence (which when walking backwards is the last one !) within that list
    3. Write the updated list into your file