Home | History | Annotate | Download | only in input
      1 /*
      2  * Licensed to the Apache Software Foundation (ASF) under one or more
      3  * contributor license agreements.  See the NOTICE file distributed with
      4  * this work for additional information regarding copyright ownership.
      5  * The ASF licenses this file to You under the Apache License, Version 2.0
      6  * (the "License"); you may not use this file except in compliance with
      7  * the License.  You may obtain a copy of the License at
      8  *
      9  *      http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 package org.apache.commons.io.input;
     18 
     19 import java.io.IOException;
     20 import java.io.InputStream;
     21 
     22 /**
     23  * Proxy stream that closes and discards the underlying stream as soon as the
     24  * end of input has been reached or when the stream is explicitly closed.
     25  * Not even a reference to the underlying stream is kept after it has been
     26  * closed, so any allocated in-memory buffers can be freed even if the
     27  * client application still keeps a reference to the proxy stream.
     28  * <p>
     29  * This class is typically used to release any resources related to an open
     30  * stream as soon as possible even if the client application (by not explicitly
     31  * closing the stream when no longer needed) or the underlying stream (by not
     32  * releasing resources once the last byte has been read) do not do that.
     33  *
     34  * @version $Id: AutoCloseInputStream.java 610010 2008-01-08 14:50:59Z niallp $
     35  * @since Commons IO 1.4
     36  */
     37 public class AutoCloseInputStream extends ProxyInputStream {
     38 
     39     /**
     40      * Creates an automatically closing proxy for the given input stream.
     41      *
     42      * @param in underlying input stream
     43      */
     44     public AutoCloseInputStream(InputStream in) {
     45         super(in);
     46     }
     47 
     48     /**
     49      * Closes the underlying input stream and replaces the reference to it
     50      * with a {@link ClosedInputStream} instance.
     51      * <p>
     52      * This method is automatically called by the read methods when the end
     53      * of input has been reached.
     54      * <p>
     55      * Note that it is safe to call this method any number of times. The original
     56      * underlying input stream is closed and discarded only once when this
     57      * method is first called.
     58      *
     59      * @throws IOException if the underlying input stream can not be closed
     60      */
     61     public void close() throws IOException {
     62         in.close();
     63         in = new ClosedInputStream();
     64     }
     65 
     66     /**
     67      * Reads and returns a single byte from the underlying input stream.
     68      * If the underlying stream returns -1, the {@link #close()} method is
     69      * called to automatically close and discard the stream.
     70      *
     71      * @return next byte in the stream, or -1 if no more bytes are available
     72      * @throws IOException if the stream could not be read or closed
     73      */
     74     public int read() throws IOException {
     75         int n = in.read();
     76         if (n == -1) {
     77             close();
     78         }
     79         return n;
     80     }
     81 
     82     /**
     83      * Reads and returns bytes from the underlying input stream to the given
     84      * buffer. If the underlying stream returns -1, the {@link #close()} method
     85      * i called to automatically close and discard the stream.
     86      *
     87      * @param b buffer to which bytes from the stream are written
     88      * @return number of bytes read, or -1 if no more bytes are available
     89      * @throws IOException if the stream could not be read or closed
     90      */
     91     public int read(byte[] b) throws IOException {
     92         int n = in.read(b);
     93         if (n == -1) {
     94             close();
     95         }
     96         return n;
     97     }
     98 
     99     /**
    100      * Reads and returns bytes from the underlying input stream to the given
    101      * buffer. If the underlying stream returns -1, the {@link #close()} method
    102      * i called to automatically close and discard the stream.
    103      *
    104      * @param b buffer to which bytes from the stream are written
    105      * @param off start offset within the buffer
    106      * @param len maximum number of bytes to read
    107      * @return number of bytes read, or -1 if no more bytes are available
    108      * @throws IOException if the stream could not be read or closed
    109      */
    110     public int read(byte[] b, int off, int len) throws IOException {
    111         int n = in.read(b, off, len);
    112         if (n == -1) {
    113             close();
    114         }
    115         return n;
    116     }
    117 
    118     /**
    119      * Ensures that the stream is closed before it gets garbage-collected.
    120      * As mentioned in {@link #close()}, this is a no-op if the stream has
    121      * already been closed.
    122      * @throws Throwable if an error occurs
    123      */
    124     protected void finalize() throws Throwable {
    125         close();
    126         super.finalize();
    127     }
    128 
    129 }
    130