views:

613

answers:

4

I am writing to a text file using a BufferedWriter but the BufferedWriter does not write to the file until the program I'm running is finished and I'm not sure how to update it as the BufferedWriter is supposedly writing. Here is some of my code that I have:

FileWriter fw = null;
try {
    fw = new FileWriter("C:/.../" + target + ".pscr",true);
    writer = new BufferedWriter(fw);
    writer.write(target);
    writer.newLine();
    writer.write(Integer.toString(listOfFiles.length));
    writer.newLine();
    for(int i=0; i < listOfFiles.length; i++){
        writer.write(probeArray[i] + "\t" + probeScoreArray[i]);
        writer.newLine();                               
    }                           
}
catch (IOException e1) {e1.printStackTrace();}
catch (RuntimeException r1) {r1.printStackTrace();}
finally {
    try {
        if(writer != null){
            writer.flush();
            writer.close();
        }
    }
    catch (IOException e2) {e2.printStackTrace();}
}

I do flush the BufferedWriter but still have no file as soon as it writes, but instead when the program finishes. Any suggestions?

+3  A: 

You need to move the flush() call into the try block. For example after every newLine() call.

That said, the flush() in finally is superfluous as close() already implicitly calls it.

BalusC
I believe I did tried that before and it didn't work but I did move it back to try it again and still the same result
Brandon
Then the file is apparently already opened/locked by something else inside the same program. What if you try to write it to a different file? E.g. "c:/test.txt" or so.
BalusC
The file is created only at that point in time. There are no other existing files with that name.
Brandon
What platform? What JVM version? Can't reproduce this here at WinXP with 1.6.0_17-b04. I've also never seen this issue before. Isn't the problem more in the way how you tested/verified if the lines were written/flushed?
BalusC
running in eclipse with JVM 1.6.0_17...how else could I test to see if it has been written/flushed besides checking to see if there was a file created?
Brandon
Yes.. But **how** are you currently checking it? F5'ing the file in Eclipse or so? Rather test it by writing to the stdout console instead of file, or check if file size grows in Windows explorer, or use a realtime file tailing program like TailXP (if you're using Windows).
BalusC
A: 

try fw.close() instead of writer.close()

splix
This doesn't make difference. The `close()` is called through in the decorated writer.
BalusC
Yep, I realized that when thinking about that a little further...I did try it though to make sure, but still the same result
Brandon
It does make a difference - it makes it worse, because BufferedWriter.flush() won't be called. You must always close the outermost stream/reader/writer, which flushes and closes itself and all the others.
EJP
@EJP: very true :) Good to see you here as well.
BalusC
A: 

Skip the buffering completely:

You're only every printing whole lines as it is, so the benefits it offers over a PrintWriter is lost in the the example above, due to the flush calls after every line write.
As described here: http://java.sun.com/javase/6/docs/api/java/io/BufferedWriter.html

PrintWriter pw = null;
try {
    pw = new PrintWriter(new FileWriter("C:/.../" + target + ".pscr", true), true);
    pw.println(target);
    pw.println(Integer.toString(listOfFiles.length));
    for(int i=0; i < listOfFiles.length; i++)
        pw.println(probeArray[i] + "\t" + probeScoreArray[i]);
}

Last update:
Called the PrintWriter(Writer out, boolean autoFlush) constructor, which according to the Javadoc, has the following behavior:

autoFlush - if true, the println, printf, or format methods will flush the output buffer

If this doesn't work I don't know what will..

Tim
I tried both ways and nothing...plus neither the BufferedWriter nor the FileWriter has a writeln() method
Brandon
@Brandon: Sorry, didn't have an IDE handy.. Updated my second example to work with a PrintWriter http://java.sun.com/javase/6/docs/api/java/io/PrintWriter.html which should have automatic flushing enabled, and should thus work correctly. Might I ask _how_ you're testing if the file is flushed correctly while running the program?
Tim
well if it is flushed then a file would be created the first time something is processed and continue to output to the file...but it's not creating the file until the end after everything has been processed.
Brandon
I tried to implement the PrintWriter the same way as I did the BufferedWriter and that didn't work either...
Brandon
@Brandon: Did you call the correct PrintWriter and FileWriter constructors? Both should have a boolean true added, the first to indicate you want to autoflush on each line, the second to indicate enabling appending.. The code sample above should work as it is..
Tim
i'll have to check on that...i'm not sure that i did or not
Brandon
A: 

Just to be completely clear, this is where you need to add the flush, if you want to flush each line as it's written:

for(int i=0; i < listOfFiles.length; i++){
    writer.write(probeArray[i] + "\t" + probeScoreArray[i]);
    writer.newLine();
    writer.flush(); // Make sure the flush() is inside the for loop
}

In your code, the flush() isn't happening until the end of the program, because the finally{} block doesn't execute until after the try{} or catch{} block has finished executing.

rob
yep i changed that a little while ago...
Brandon