ก็เลยเป็นที่มาของบทความวันนี้ครับ ว่าเราจะทำยังไงให้มันปิด InputStream เองโดยอัตโนมัติเมื่อมันทำงานเสร็จ
วิธีแก้ปัญหา โดยการสร้าง class AutoCloseInputStream ขึ้นมาจัดการกับปัญหานี้ โดยหน้าที่ของ class นี้คือจะห่อหุ้ม หรือ wrap InputStream อีกที เมื่อมีการอ่านข้อมูลจาก stream เสร็จแล้ว (in.read คืนค่าเป็น -1) AutoCloseInputStream ก็จะทำการ close stream นั้นให้เองโดยอัตโนมัติ แค่นี้ก็หมดปัญหาเรื่อง auto close ไปแล้วครับ
AutoCloseInputStream.java
package com.blogspot.na5cent.io.util; import java.io.IOException; import java.io.InputStream; /** * for wrap InputStream then Automatic close */ public class AutoCloseInputStream extends InputStream { private final InputStream in; private boolean closed; public AutoCloseInputStream(InputStream in) { this.in = in; } private int autoClose(int x) throws IOException { if (x < 0) { close(); } return x; } @Override public void close() throws IOException { if (!closed) { in.close(); closed = true; } } @Override public int read(byte[] b, int off, int len) throws IOException { return closed ? -1 : autoClose(in.read(b, off, len)); } @Override public int read(byte[] b) throws IOException { return closed ? -1 : autoClose(in.read(b)); } public int read() throws IOException { return closed ? -1 : autoClose(in.read()); } }แต่ยังมีอีกปัญหาตามมาครับ ปัญหาใหญ่เลยแหล่ะ คำถามคือ แล้วถ้ามันเกิด Exception ขึ้นมาก่อนที่ InputStream จะทำงานเสร็จล่ะ มันก็ไม่ปิดสิ!!!
Apache common แก้ปัญหานี้ด้วยการสร้าง ProxyInputStream ขึ้นมาครอบอีกชั้นครับ แล้วส่ง InputStream เข้าไปปิดข้างในอีกที ซึ่งถ้ามันเกิด Exception ในระหว่างการอ่านข้อมูล แล้วมีการ throw Exception ออกมา มันก็รับประกันได้ว่า InputStream นั้นจะถูกปิดเสมอ ไม่ว่าจะด้วยกรณีใดๆ ก็ตามครับ
AutoCloseImputStream Apache Common Document API : http://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/input/AutoCloseInputStream.html
ไม่มีความคิดเห็น:
แสดงความคิดเห็น