14

I want to delete some content of file using java program as below. Is this the write method to replace in the same file or it should be copied to the another file.

But its deleting the all content of the file.

class FileReplace
{
    ArrayList<String> lines = new ArrayList<String>();
    String line = null;
    public void  doIt()
    {
        try
        {
            File f1 = new File("d:/new folder/t1.htm");
            FileReader fr = new FileReader(f1);
            BufferedReader br = new BufferedReader(fr);
            while (line = br.readLine() != null)
            {
                if (line.contains("java"))
                    line = line.replace("java", " ");
                lines.add(line);
            }
            FileWriter fw = new FileWriter(f1);
            BufferedWriter out = new BufferedWriter(fw);
            out.write(lines.toString());
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }
    }
    public statc void main(String args[])
    {
        FileReplace fr = new FileReplace();
        fr.doIt();
    }
}
Adesh singh
  • 2,083
  • 9
  • 24
  • 36

6 Answers6

20

I would start with closing reader, and flushing writer:

public class FileReplace {
    List<String> lines = new ArrayList<String>();
    String line = null;

    public void  doIt() {
        try {
            File f1 = new File("d:/new folder/t1.htm");
            FileReader fr = new FileReader(f1);
            BufferedReader br = new BufferedReader(fr);
            while ((line = br.readLine()) != null) {
                if (line.contains("java"))
                    line = line.replace("java", " ");
                lines.add(line);
            }
            fr.close();
            br.close();

            FileWriter fw = new FileWriter(f1);
            BufferedWriter out = new BufferedWriter(fw);
            for(String s : lines)
                 out.write(s);
            out.flush();
            out.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public static void main(String args[]) {
        FileReplace fr = new FileReplace();
        fr.doIt();
    }
}
ByteHamster
  • 4,884
  • 9
  • 38
  • 53
Mateusz
  • 2,287
  • 20
  • 28
14

The accepted answer is great. However, there is an easier way to replace content in a file using Apache's commons-io library (commons-io-2.4.jar - you can use any latest versions)

private void update() throws IOException{
        File file = new File("myPath/myFile.txt");
        String fileContext = FileUtils.readFileToString(file);
        fileContext = fileContext.replaceAll("_PLACEHOLDER_", "VALUE-TO-BE-REPLACED");
        FileUtils.write(file, fileContext);
 }

Note: Thrown IOException needs to be caught and handled by the application accordingly.

Somnath Musib
  • 3,548
  • 3
  • 34
  • 47
Sandeep Salian
  • 341
  • 2
  • 8
  • Why is this better? It seems like it is doing the same thing... or at the very least just copying the file to a string and rewriting the file? Why do you need Apache for this? – Sam Apr 07 '21 at 04:16
3

Read + write to the same file simulatenously is not ok.

EDIT: to rephrase and be more correct and specific - reading and writing to the same file, in the same thread, without properly closing the reader (and flusing the writer) is not ok.

acostache
  • 2,177
  • 7
  • 23
  • 48
  • 1
    Could you please elaborate why ? – Damian Leszczyński - Vash Dec 06 '12 at 10:48
  • 1
    Yes, generally speaking, a reason would be because the offsets within the file will shift everytime you make a write and the read cursor will not keep track of that (see the accepted answer here: http://stackoverflow.com/questions/4251058/java-read-and-write-a-file-together). Still, after rereading this question, the problem here was not that (i answered too fast), but a mattering of not closing and flusing. – acostache Dec 06 '12 at 10:56
2

Make sure to:

  • close any stream when you no longer need them
  • In particular before reopening it for writing.
  • truncate the file, to make sure it shrinks if you write less than it had.
  • then write the output
  • write individual lines, don't rely on toString.
  • flush and close when you are finished writing!

If you use buffered IO, you always have to ensure that the buffer is flushed at the end, or you might lose data!

Has QUIT--Anony-Mousse
  • 76,138
  • 12
  • 138
  • 194
  • I'm not sure he is reading/writing at the same time. He reads the lines into a list, then writes the list to file, or at least is attempting to. – Qwerky Dec 06 '12 at 10:48
0

I can see three problems.

First you are writing to out which I assume is System.out, not an output stream to the file.

Second, if you do write to an output stream to the file, you need to close it.

Third, the toString() method on an ArrayList isn't going to write the file like you are expecting. Loop over the list and write each String one at a time. Ask yourself whether you need to write newline characters as well.

Qwerky
  • 18,217
  • 6
  • 44
  • 80
0

The accepted answer is slightly wrong. Here's the correct code.

    public class FileReplace {
List<String> lines = new ArrayList<String>();
String line = null;

public void  doIt() {
    try {
        File f1 = new File("d:/new folder/t1.htm");
        FileReader fr = new FileReader(f1);
        BufferedReader br = new BufferedReader(fr);
        while ((line = br.readLine()) != null) {
            if (line.contains("java"))
                line = line.replace("java", " ");
            lines.add(line);
        }
        fr.close();
        br.close();

        FileWriter fw = new FileWriter(f1);
        BufferedWriter out = new BufferedWriter(fw);
        for(String s : lines)
             out.write(s);
        out.flush();
                } 
        out.close();
   catch (Exception ex) {
        ex.printStackTrace();
    }
}
Ravi K M
  • 77
  • 4
  • 16
  • 1
    Yes. "out.close()" should be out of "for" loop. – Ravi K M Oct 14 '16 at 13:15
  • It is outside of the for loop. The `for` loop is only the next line, as the braces have been emitted. You have put it outside of the `try` block. A better solution would have been to put the readers inside `using{...}` blocks – Karl Gjertsen Oct 14 '16 at 17:18