หน้าเว็บ

วันจันทร์ที่ 25 พฤศจิกายน พ.ศ. 2556

AutoCloseInputStream : java

        บางครั้งเราต้องเจอกับสถานการณ์ที่เวลาเขียนโปรแกรมไปแล้ว  ไม่สามารถปิด InputStream ได้ในทันที  เพราะเมื่อเราทำการปิด  InputStream ก็เท่ากับว่า เราตั้งใจที่จะไม่ใช้งาน InputStream นั้นอีกต่อไป แล้วเราจะแก้ปัญหานี้ยังไง  ปิดก็ใช้งานไม่ได้  ไม่ปิดก็ไม่ได้ เดี๋ยวเกิด Resource Lock (ในกรณีที่เป็น FileInputStream) หรือ memory เต็มอีก (ในกรณีที่เป็น ByteArrayInputStream) สรุปแล้วคือต้องปิดครับ  แล้วเราจะปิดยังไงล่ะ?

ก็เลยเป็นที่มาของบทความวันนี้ครับ ว่าเราจะทำยังไงให้มันปิด 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

ไม่มีความคิดเห็น:

แสดงความคิดเห็น