    001    /*
    002     * Licensed to the Apache Software Foundation (ASF) under one or more
    003     * contributor license agreements.  See the NOTICE file distributed with
    004     * this work for additional information regarding copyright ownership.
    005     * The ASF licenses this file to You under the Apache License, Version 2.0
    006     * (the "License"); you may not use this file except in compliance with
    007     * the License.  You may obtain a copy of the License at
    008     *
    009     *      http://www.apache.org/licenses/LICENSE-2.0
    010     *
    011     * Unless required by applicable law or agreed to in writing, software
    012     * distributed under the License is distributed on an "AS IS" BASIS,
    013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014     * See the License for the specific language governing permissions and
    015     * limitations under the License.
    016     */
    017    package org.apache.commons.io.input;
    018
    019    import java.io.IOException;
    020    import java.io.InputStream;
    021
    022    /**
    023     * Proxy stream that closes and discards the underlying stream as soon as the
    024     * end of input has been reached or when the stream is explicitly closed.
    025     * Not even a reference to the underlying stream is kept after it has been
    026     * closed, so any allocated in-memory buffers can be freed even if the
    027     * client application still keeps a reference to the proxy stream.
    028     * <p>
    029     * This class is typically used to release any resources related to an open
    030     * stream as soon as possible even if the client application (by not explicitly
    031     * closing the stream when no longer needed) or the underlying stream (by not
    032     * releasing resources once the last byte has been read) do not do that.
    033     *
    034     * @version $Id: AutoCloseInputStream.java 1003647 2010-10-01 20:53:59Z niallp $
    035     * @since Commons IO 1.4
    036     */
    037    public class AutoCloseInputStream extends ProxyInputStream {
    038
    039        /**
    040         * Creates an automatically closing proxy for the given input stream.
    041         *
    042         * @param in underlying input stream
    043         */
    044        public AutoCloseInputStream(InputStream in) {
    045            super(in);
    046        }
    047
    048        /**
    049         * Closes the underlying input stream and replaces the reference to it
    050         * with a {@link ClosedInputStream} instance.
    051         * <p>
    052         * This method is automatically called by the read methods when the end
    053         * of input has been reached.
    054         * <p>
    055         * Note that it is safe to call this method any number of times. The original
    056         * underlying input stream is closed and discarded only once when this
    057         * method is first called.
    058         *
    059         * @throws IOException if the underlying input stream can not be closed
    060         */
    061        @Override
    062        public void close() throws IOException {
    063            in.close();
    064            in = new ClosedInputStream();
    065        }
    066
    067        /**
    068         * Automatically closes the stream if the end of stream was reached.
    069         *
    070         * @param n number of bytes read, or -1 if no more bytes are available
    071         * @throws IOException if the stream could not be closed
    072         * @since Commons IO 2.0
    073         */
    074        @Override
    075        protected void afterRead(int n) throws IOException {
    076            if (n == -1) {
    077                close();
    078            }
    079        }
    080
    081        /**
    082         * Ensures that the stream is closed before it gets garbage-collected.
    083         * As mentioned in {@link #close()}, this is a no-op if the stream has
    084         * already been closed.
    085         * @throws Throwable if an error occurs
    086         */
    087        @Override
    088        protected void finalize() throws Throwable {
    089            close();
    090            super.finalize();
    091        }
    092
    093    }