tags:

views:

106

answers:

3

i am using the following code to write an array to the file:

FileWriter fstream1=new FileWriter("outx.txt");
BufferedWriter out1= new BufferedWriter(fstream1);
FileWriter fstream2=new FileWriter("outy.txt");
BufferedWriter out2= new BufferedWriter(fstream2);
for(int i=0;i<320*240;i++)
{

        out1.write(0+System.getProperty("line.separator"));//
       // out1.write("\n");
        out2.write(0+System.getProperty("line.separator"));
//out2.write("\n");

}

: here in the above code i am putting all zeros the file should be containing 76800 lines( 0s) but my file is having only 69932 lines. what is the problem and if you can suggest some other way to do this.

+4  A: 

Add:

out1.flush();
out2.flush();

After the for loop.

It is likely that your program is exiting before the buffers in the BufferedReader have been flushed, a common problem with working with buffered output.

Edit: The more correct solution would be:

public static void main(String[] args) throws IOException {
    final String outputString = "0" + System.getProperty("line.separator");
    BufferedWriter out1 = null;
    BufferedWriter out2 = null;
    try {
        out1 = new BufferedWriter(new FileWriter("outx.txt"));
        out2 = new BufferedWriter(new FileWriter("outy.txt"));
        for(int i = 0; i < 320 * 240; i++) {
            out1.write(outputString);
            out2.write(outputString);
        }
        out1.flush(); // Not really needed as close will flush, but it is 
        out2.flush(); // useful for describing the intent of the code
    } finally {
        closeQuietly(out1);
        closeQuietly(out2);
    }
}

private static void closeQuietly(Closeable c) {
    try {
        if (c != null) {
            c.close();
        }
    } catch (Exception e) {
        // No-op
    }
}
Michael Barker
Flushing alone is not enough. You should explicitly close the streams to free resources. The `close()` will already implicitly flush the buffers.
BalusC
+5  A: 

Did you remember to close the output streams? Your example doesn't list the calls to close(), which should flush the streams as well. BufferedWriter's default behavior is to flush (write) its remaining contents before closing the stream it is buffering.

You should probably add:

out1.close();
out2.close();

It is a very common case when the end of a file is being cut off that you forgot to close the writer used to create the file, especially when you have used a BufferedOutputStream or BufferedWriter that may not flush its buffer (write it to the file) until it has been explicitly flushed (or more commonly, closed).

It is a very good habit to get into to immediately write the close() call after opening the stream, and then write all of your code for working with the stream between the calls. Taking exceptions into account, the standard calls use the following idiom:

Writer myOutWriter = null;
try {
   myOutWriter = new BufferedWriter(new FileWriter("..."));
   // Write to myOutWriter here
} catch (IOException ioe) {
   // Handle any exceptions here
} finally { 
   try {
      if (myOutWriter != null) {
         myOutWriter.close();
      }
   } catch (IOException ioe) {
      // Not much you can do here
   }
}

The Apache Commons IO Project (http://commons.apache.org/io/) has a nice utility called IOUtils.closeQuietly() that cleans up the finally block by including the try catch, null check, and call to close into one method call. An example using that library would look like this:

Writer myOutWriter = null;
try {
   myOutWriter = new BufferedWriter(new FileWriter("..."));
   // Write to myOutWriter here
} catch (IOException ioe) {
   // Handle any exceptions here
} finally { 
   IOUtils.closeQuietly(myOutWriter);
}
mwooten.dev
1) You could rewrite your first code block to eliminate a catch block and a pointless null assignment.2) If you use `closeQuietly` like this, your application could commit incomplete data to the file and would not handle the error. This is because close may write data.
McDowell
+1  A: 

As others have pointed out, it is likely that there is unflushed data in your buffers.

An acceptable way to rewrite your code would be like this:

Writer out1 = new FileWriter("outx.txt");
try {
  out1 = new BufferedWriter(out1);
  Writer out2 = new FileWriter("outy.txt");
  try {
    out2 = new BufferedWriter(out2);
    for (int i = 0; i < 320 * 240; i++) {
      out1.write(0 + System.getProperty("line.separator"));
      out2.write(0 + System.getProperty("line.separator"));
    }
  } finally {
    out2.close();
  }
} finally {
  out1.close();
}

This code:

  • will flush data via close
  • will always release file handles via close, even if an error occurs (by using finally)
  • obeys the contract for the Closeable classes
  • doesn't muck around with null or swallow exceptions
McDowell