What is the correct way to open a stream in Java

I will be giving a Java lecture to physics students and I would like to know how to open the file correctly.

In many of my professional applications, I have done something like this:

  BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("file")));
  try{
    ....
  }finally {
     bufferedWriter.close();
  }

      

which is IMHO OK, meaning the reader will be closed.

When I was putting this in an example for my students, I was wondering what would happen if the constructor InputStreamReader

throws an exception --- FileInputStream will be open, but my code will not be closed (since these objects are created outside the try-finally block.

So this is the correct idiom, and if so, why? If this is the wrong idiom to open a stream, please point me to the correct one!

Edit . I am looking for an idiom that is correct and very easy to write and understand, physics students are new to programming.

Edit . It's stupid to me. I copied the wrong example. If I use Writers instead of readers, it gets more complicated.

+3


source to share


2 answers


Reading with input streams

Before Java 7 this is how you can do it

InputStream in = null;
try {
     in = new FileInputStream("simple.csv");
     BufferedReader buf = new BufferedReader(new InputStreamReader(in));
} finally {
  if (in != null) {
     try {
         in.close();
     } catch (IOException e) {}
  }
}

      

For Java 7, you can use Closeable

something like

try (BufferedReader buf = new BufferedReader(...)) {}

      


EDIT: Why didn't I close the buf

above? Look at the source codeBufferedReader.close()



public void close() throws IOException {
    synchronized (lock) {
        if (in == null)
            return;
        in.close();
        in = null;
        cb = null;
    }
}

      


Recording with output streams

EDIT 2: The same principle applies to writers. However, if you are really interested in the flow of the thread when happens IOException

, then you should check both writer

and stream

for null

and try closing them accordingly. This does provide a lot of additional code, though. It might look something like this:

BufferedWriter buf = null;
OutputStream out = null;
try {
    out = new FileOutputStream("file");
    buf = new BufferedWriter(new OutputStreamWriter(out));
} finally {
  if (buf != null) {
     try { buf.close(); } catch (IOException ex){}
  }
  if (out != null) {
     try { out.close(); } catch (IOException ex){}
  }
}

      

It's not pretty. You can introduce a helper procedure to close your streams or search in Java 7, orApache IOUtils

+4


source


In this special case (nested constructors) FileInputStream

will remain open. You will need to do it like this (if you really need to make sure the stream is closed):

final FileInputStream fis = new FileInputStream("");
try
{
    final BufferedReader br = new BufferedReader(new InputStreamReader(fis));
    // ...
}
finally
{
    fis.close();
}

      



The closure FileInputStream

should be sufficient.

Edit: The same logic can apply to writers. If the open FileOutputStream

fails, it throws an exception that prevents the try / finally block from being executed. And if any other write constructor fails, the output stream is still closed with a clause final

.

0


source







All Articles