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