Writing 1: Close the stream in try instead of finally
try { OutputStream out = new FileOutputStream("file"); // ...operation flow code out.close(); } catch (Exception e) { e.printStackTrace(); }
When the operation stream code reports an error, this writing method will cause the stream to not be closed normally, so it is not recommended!
The correct operation method should be completed in finally
. The example code is as follows:
OutputStream out = null; try { out = new FileOutputStream("file"); // ...operation flow code } catch (Exception e) { e.printStackTrace(); } finally { // Close in finally to ensure it can be executed try { if (out != null) { out.close(); } } catch (Exception e) { e.printStackTrace(); } }
Writing 2: When closing multiple streams, put them in a try
When closing multiple streams, some students find it troublesome and put it in a try. The example code is as follows:
OutputStream out1 = null; OutputStream out2 = null; try { out1 = new FileOutputStream("file"); out2 = new FileOutputStream("file"); // ...operation flow code } catch (Exception e) { e.printStackTrace(); } finally { try { if (out1 != null) { // If an exception occurs here, the out2 stream is not closed out1.close(); } if (out2 != null) { out2.close(); } } catch (Exception e) { e.printStackTrace(); } }
In this way of writing, when out1.close
throws an exception, out2.close
will not be closed normally, so it is not recommended !
The correct operation method should be to close
one by one. Don’t be lazy. The example code is as follows:
OutputStream out1 = null; OutputStream out2 = null; try { out1 = new FileOutputStream("file"); out2 = new FileOutputStream("file"); // ...operation flow code } catch (Exception e) { e.printStackTrace(); } finally { try { if (out1 != null) { out1.close(); } } catch (Exception e) { e.printStackTrace(); } try { if (out2 != null) { out2.close(); } } catch (Exception e) { e.printStackTrace(); } }
Writing method 3: Create the stream in the loop and close it outside the loop
Some students close the file stream outside the loop when operating multiple files in a loop. The example code is as follows:
OutputStream out = null; try { for (int i = 0; i < 10; i + + ) { out = new FileOutputStream("file"); // ...operation flow code } } catch (Exception e) { e.printStackTrace(); } finally { try { if (out != null) { out.close(); } } catch (Exception e) { e.printStackTrace(); } }
On the surface, there seems to be no problem, but in fact 10 IO streams are created. After the logic in try is executed, only the last IO stream object is assigned to the out
parameter. That is, after the program is executed, only the last IO stream is closed, and the other 9 IO streams are useless and manually closed, so it is not recommended!
The correct operation method should be close
in the loop body. Don’t be lazy. The example code is as follows:
for (int i = 0; i < 10; i + + ) { OutputStream out = null; try { out = new FileOutputStream("file"); // ...operation flow code } catch (Exception e) { e.printStackTrace(); } finally { try { if (out != null) { out.close(); } } catch (Exception e) { e.printStackTrace(); } } }
Writing method 4: When closing multiple streams, there is no need to follow the define-first-release principle
When some students operate multiple file streams, after the operation is completed, they close the file streams in order. The example code is as follows:
FileOutputStream fos = null; BufferedOutputStream bos = null; try { fos = new FileOutputStream("file"); bos = new BufferedOutputStream(fos); // ...operation flow code } catch (Exception e){ } finally { //Close the streams one by one try { fos.close(); } catch (IOException e) { e.printStackTrace(); } try { // java.io.IOException: Stream Closed error will be reported here bos.close(); } catch (IOException e) { e.printStackTrace(); } }
Close the file stream in order. In this way, java.io.IOException: Stream Closed
error may be reported.
The reason is that BufferedOutputStream
depends on FileOutputStream
. If you close the FileOutputStream
stream directly and then close BufferedOutputStream
again, you will be prompted that the source has been Closed, buffer data cannot be output.
The correct operation method should follow the principle of define later and release first. The example code is as follows:
FileOutputStream fos = null; BufferedOutputStream bos = null; try { fos = new FileOutputStream("file"); bos = new BufferedOutputStream(fos); // ...operation flow code } catch (Exception e){ } finally { // Define later and release first try { bos.close(); } catch (IOException e) { e.printStackTrace(); } try { fos.close(); } catch (IOException e) { e.printStackTrace(); } }
Writing method 5: jdk7 and above, it is recommended to use try-with-resources writing method
try-with-resources
is a new exception handling mechanism introduced in JDK 7, which allows developers to avoid explicitly releasing the resources used in the try-catch
statement block. resource.
Taking the above example, it can be changed to the following writing:
try (FileOutputStream fos = new FileOutputStream("file"); BufferedOutputStream bos = new BufferedOutputStream(fos)){ // ...operation flow code } catch (Exception e){ e.printStackTrace(); }
try-with-resources
The operation of releasing resources also follows the principle of release first after definition!
Writing method 6: When using the packaging flow, you only need to close the last packaging flow
Packaging stream refers to the IO stream class implemented through the decoration design pattern. Its purpose is to extend the functions of the underlying stream. When actual data is transmitted, the underlying stream is still used for transmission. For example, the buffered byte output stream BufferedOutputStream
is a wrapper stream. Its purpose is to provide a buffer function for the byte output stream to make data output more efficient.
When using the packaging flow, we only need to close the last packaging flow.
Taking the above as an example, the rewritten example code is as follows:
InputStream is = null; InputStreamReader isr = null; BufferedReader br = null; try { is = new FileInputStream("file"); isr = new InputStreamReader(is); br = new BufferedReader(isr); // ...operation flow code } catch (Exception e){ e.printStackTrace(); } finally { //Closing the wrapper stream will also automatically close the InputStream stream try { br.close(); } catch (IOException e) { e.printStackTrace(); } }
Summarize:
In the above, we mentioned that as long as it is an IO stream, it is recommended that everyone close the resource on the mobile phone. However, there is a stream in Java that does not need to be closed manually, such as the memory read and write stream: ByteArrayInputStream
, ByteArrayOutputStream
.
Different from streams pointing to the hard disk, ByteArrayInputStream
and ByteArrayOutputStream
are actually byte arrays disguised as streams stored in memory (just think of them as byte data) , they will not lock any file handles and ports, and if no longer used, the byte array will be garbage collected, so there is no need to close it.
When the IO stream points to external resources such as memory card/hard disk/network, it must be closed manually.
The knowledge points of the article match the official knowledge files, and you can further learn related knowledge. Java Skill TreeHomepageOverview 138778 people are learning the system