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 1304052 2012-03-22 20:55:29Z ggregory $
035     * @since 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 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    }