Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange behavior in writing to file

I was trying some basic Java I/O operations, I try to run the below code :

public static void main(String[] args) {
    File file = new File("fileWrite2.txt"); // create a File object
      try {
    FileWriter fr = new FileWriter(file);
    PrintWriter pw = new PrintWriter(file); // create a PrintWriter that will send its output to a Writer
    BufferedWriter br =  new BufferedWriter(fr);
    br.write("sdsadasdsa");br.flush();br.append("fffff");br.flush();
    pw.println("howdy"); // write the data
    pw.println("folks");
    pw.flush();
    pw.close();
    } catch (IOException e) {
       e.printStackTrace();
    }
}

When I run the above I get the following output in the file created :

howdy
folks
f

Can anyone explain why the 'f' is coming in the last line ?

like image 609
Twaha Mehmood Avatar asked Nov 14 '13 07:11

Twaha Mehmood


3 Answers

The f comes from the left over string of br.append("fffff"); which was written in the file by the BufferedWriter.

Since both BufferedWriter and PrintWriter write to the same file, the contents written by the PrintWriter overwrite the contents written by the BufferedWriter.

But seems the no. of bytes written by PrintWriter fall short by 1 to completely overwrite the data written by BufferedWriter and thus you get the f.

If you change this br.append("fffff"); to br.append("ffffg");, you can see that the g is now left over. Alternatively, changing pw.println("folks"); to pw.println("folks1"); will show that the previously written data is now completely overwritten by the PrintWriter.

All this confusion is because of having 2 different writers for the same file object which is the cause of the problem. As @Boris pointed out, have just 1 writer for a file object.

Note: Another interesting thing to test out would be to move the second br.flush(); after the pw.flush();.

// br.flush(); // moved from here
pw.println("howdy"); // write the data
pw.println("folks");
pw.flush();
br.flush(); // to here
like image 132
Rahul Avatar answered Nov 11 '22 23:11

Rahul


You are writing 15 characters on the bufferedwriter by doing this `

br.write("sdsadasdsa");
br.flush();
br.append("fffff");`

But when you are writng on printWriter, it overwrites the content of the file this time you are writing

pw.println("howdy"); // write the data
pw.println("folks");

which is 10 characters only with two new line \n which takes 2 bytes since we use println because \n in windows will transform to \r\n . So total of 14. so 1 character remains there which is f

like image 3
shikjohari Avatar answered Nov 12 '22 00:11

shikjohari


In your code the following steps are executed.

1 When

br.write("sdsadasdsa");br.flush();br.append("fffff");br.flush();

is executed.

The file content will be

sdsadasdsafffff

2 when pw.println("howdy"); is calling.

String howdy override the first 5 character sdsad and a new line terminates the line. In txt, 2 characters are needed \r\n, this will over write another 2 character .Then the file content will be as follows:

howdy

dsafffff

3 when pw.println("folks"); is executed.

Since it is not called flush() method in step#2. String folks will over write the second line content in file. and a new line to over write another 2 characters.

Then the following content will be stored in file:

howdy

folks

f
like image 2
MouseLearnJava Avatar answered Nov 11 '22 23:11

MouseLearnJava