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
java java-io


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 to share


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 to share







All Articles
Loading...
X
Show
Funny
Dev
Pics