When you're through with a stream, you should close it. This allows the operating system to free any resources associated with the stream. Exactly what these resources are depends on your platform and varies with the type of stream. However, many systems have finite resources. For example, on some personal computer operating systems, no more than several hundred files can be open at once. Multiuser operating systems have larger limits, but limits nonetheless.
To close a stream, invoke its close( ) method:
public void close( ) throws IOException
For example, again assuming out is an OutputStream, calling out.close( ) closes the stream and frees any underlying resources such as file handles or network ports associated with the stream.
Once you have closed an output stream, you probably can't write anything else onto that stream. Attempting to do so normally throws an IOException, though there are a few classes where this doesn't happen.
|
Not all streams need to be closedbyte array output streams do not need to be closed, for example. However, streams associated with files and network connections should always be closed when you're done with them. For example, if you open a file for writing and neglect to close it when you're through, then other processes may be blocked from reading or writing to that file. Often, files are closed like this:
try { OutputStream out = new FileOutputStream("numbers.dat"); // Write to the stream... out.close( ); } catch (IOException ex) { System.err.println(ex); }
However, this code fragment has a potential leak. If an IOException is thrown while writing, the stream won't be closed. It's more reliable to close the stream in a finally block so that it's closed whether or not an exception is thrown. To do this you need to declare the OutputStream variable outside the try block. For example:
// Initialize this to null to keep the compiler from complaining // about uninitialized variables OutputStream out = null; try { out = new FileOutputStream("numbers.dat"); // Write to the stream... } catch (IOException ex) { System.err.println(ex); } finally { if (out != null) { try { out.close( ); } catch (IOException ex) { System.err.println(ex); } } }
Variable scope and nested try-catch-finally blocks make this a little uglier, yet it's quite a bit safer. The code can be a little cleaner if you have the option of propagating any IOExceptions thrown rather than catching them; that is, if the method that contains this code is declared to throw IOException. In that case, a typical call to close( ) works like this:
// Initialize this to null to keep the compiler from complaining // about uninitialized variables OutputStream out == null; try { out = new FileOutputStream("numbers.dat"); // Write to the stream... } finally { if (out != null) out.close( ); }
2.3.1. The Closeable Interface
Java 5 added a Closeable interface that the OutputStream class implements:
package java.io; public interface Closeable { void close( ) throws IOException; }
InputStream, Channel, Formatter, and various other things that can be closed also implement this interface. Personally I've never figured out the use case that justifies this extra interface, but it's there if for some reason you want to write a method that accepts only arguments that can be closed, or some such.
Basic I/O
Introducing I/O
Output Streams
Input Streams
Data Sources
File Streams
Network Streams
Filter Streams
Filter Streams
Print Streams
Data Streams
Streams in Memory
Compressing Streams
JAR Archives
Cryptographic Streams
Object Serialization
New I/O
Buffers
Channels
Nonblocking I/O
The File System
Working with Files
File Dialogs and Choosers
Text
Character Sets and Unicode
Readers and Writers
Formatted I/O with java.text
Devices
The Java Communications API
USB
The J2ME Generic Connection Framework
Bluetooth
Character Sets