14ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira/* 24ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * Licensed to the Apache Software Foundation (ASF) under one or more 34ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * contributor license agreements. See the NOTICE file distributed with 44ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * this work for additional information regarding copyright ownership. 54ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * The ASF licenses this file to You under the Apache License, Version 2.0 64ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * (the "License"); you may not use this file except in compliance with 74ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * the License. You may obtain a copy of the License at 84ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * 94ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * http://www.apache.org/licenses/LICENSE-2.0 104ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * 114ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * Unless required by applicable law or agreed to in writing, software 124ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * distributed under the License is distributed on an "AS IS" BASIS, 134ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 144ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * See the License for the specific language governing permissions and 154ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * limitations under the License. 164ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira */ 174ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereirapackage org.apache.commons.io.input; 184ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira 194ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereiraimport java.io.IOException; 204ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereiraimport java.io.InputStream; 214ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira 224ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira/** 234ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * Proxy stream that closes and discards the underlying stream as soon as the 244ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * end of input has been reached or when the stream is explicitly closed. 254ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * Not even a reference to the underlying stream is kept after it has been 264ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * closed, so any allocated in-memory buffers can be freed even if the 274ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * client application still keeps a reference to the proxy stream. 284ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * <p> 294ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * This class is typically used to release any resources related to an open 304ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * stream as soon as possible even if the client application (by not explicitly 314ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * closing the stream when no longer needed) or the underlying stream (by not 324ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * releasing resources once the last byte has been read) do not do that. 334ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * 344ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * @version $Id: AutoCloseInputStream.java 610010 2008-01-08 14:50:59Z niallp $ 354ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * @since Commons IO 1.4 364ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira */ 374ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereirapublic class AutoCloseInputStream extends ProxyInputStream { 384ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira 394ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira /** 404ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * Creates an automatically closing proxy for the given input stream. 414ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * 424ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * @param in underlying input stream 434ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira */ 444ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira public AutoCloseInputStream(InputStream in) { 454ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira super(in); 464ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira } 474ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira 484ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira /** 494ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * Closes the underlying input stream and replaces the reference to it 504ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * with a {@link ClosedInputStream} instance. 514ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * <p> 524ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * This method is automatically called by the read methods when the end 534ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * of input has been reached. 544ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * <p> 554ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * Note that it is safe to call this method any number of times. The original 564ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * underlying input stream is closed and discarded only once when this 574ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * method is first called. 584ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * 594ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * @throws IOException if the underlying input stream can not be closed 604ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira */ 614ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira public void close() throws IOException { 624ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira in.close(); 634ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira in = new ClosedInputStream(); 644ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira } 654ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira 664ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira /** 674ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * Reads and returns a single byte from the underlying input stream. 684ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * If the underlying stream returns -1, the {@link #close()} method is 694ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * called to automatically close and discard the stream. 704ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * 714ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * @return next byte in the stream, or -1 if no more bytes are available 724ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * @throws IOException if the stream could not be read or closed 734ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira */ 744ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira public int read() throws IOException { 754ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira int n = in.read(); 764ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira if (n == -1) { 774ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira close(); 784ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira } 794ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira return n; 804ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira } 814ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira 824ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira /** 834ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * Reads and returns bytes from the underlying input stream to the given 844ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * buffer. If the underlying stream returns -1, the {@link #close()} method 854ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * i called to automatically close and discard the stream. 864ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * 874ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * @param b buffer to which bytes from the stream are written 884ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * @return number of bytes read, or -1 if no more bytes are available 894ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * @throws IOException if the stream could not be read or closed 904ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira */ 914ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira public int read(byte[] b) throws IOException { 924ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira int n = in.read(b); 934ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira if (n == -1) { 944ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira close(); 954ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira } 964ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira return n; 974ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira } 984ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira 994ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira /** 1004ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * Reads and returns bytes from the underlying input stream to the given 1014ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * buffer. If the underlying stream returns -1, the {@link #close()} method 1024ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * i called to automatically close and discard the stream. 1034ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * 1044ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * @param b buffer to which bytes from the stream are written 1054ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * @param off start offset within the buffer 1064ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * @param len maximum number of bytes to read 1074ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * @return number of bytes read, or -1 if no more bytes are available 1084ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * @throws IOException if the stream could not be read or closed 1094ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira */ 1104ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira public int read(byte[] b, int off, int len) throws IOException { 1114ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira int n = in.read(b, off, len); 1124ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira if (n == -1) { 1134ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira close(); 1144ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira } 1154ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira return n; 1164ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira } 1174ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira 1184ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira /** 1194ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * Ensures that the stream is closed before it gets garbage-collected. 1204ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * As mentioned in {@link #close()}, this is a no-op if the stream has 1214ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * already been closed. 1224ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * @throws Throwable if an error occurs 1234ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira */ 1244ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira protected void finalize() throws Throwable { 1254ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira close(); 1264ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira super.finalize(); 1274ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira } 1284ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira 1294ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira} 130