File Java Tutorial

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
 * An input stream, which limits its data size. This stream is
 * used, if the content length is unknown.
 */
public abstract class LimitedInputStream
        extends FilterInputStream {
    /**
     * The maximum size of an item, in bytes.
     */
    private long sizeMax;
    /**
     * The current number of bytes.
     */
    private long count;
    /**
     * Whether this stream is already closed.
     */
    private boolean closed;
    /**
     * Creates a new instance.
     * @param pIn The input stream, which shall be limited.
     * @param pSizeMax The limit; no more than this number of bytes
     *   shall be returned by the source stream.
     */
    public LimitedInputStream(InputStream pIn, long pSizeMax) {
        super(pIn);
        sizeMax = pSizeMax;
    }
    /**
     * Called to indicate, that the input streams limit has
     * been exceeded.
     * @param pSizeMax The input streams limit, in bytes.
     * @param pCount The actual number of bytes.
     * @throws IOException The called method is expected
     *   to raise an IOException.
     */
    protected abstract void raiseError(long pSizeMax, long pCount)
            throws IOException;
    /** Called to check, whether the input streams
     * limit is reached.
     * @throws IOException The given limit is exceeded.
     */
    private void checkLimit() throws IOException {
        if (count > sizeMax) {
            raiseError(sizeMax, count);
        }
    }
    /**
     * Reads the next byte of data from this input stream. The value
     * byte is returned as an int in the range
     * 0 to 255. If no byte is available
     * because the end of the stream has been reached, the value
     * -1 is returned. This method blocks until input data
     * is available, the end of the stream is detected, or an exception
     * is thrown.
     * 
     * This method
     * simply performs in.read() and returns the result.
     *
     * @return     the next byte of data, or -1 if the end of the
     *             stream is reached.
     * @exception  IOException  if an I/O error occurs.
     * @see        java.io.FilterInputStream#in
     */
    public int read() throws IOException {
        int res = super.read();
        if (res != -1) {
            count++;
            checkLimit();
        }
        return res;
    }
    /**
     * Reads up to len bytes of data from this input stream
     * into an array of bytes. If len is not zero, the method
     * blocks until some input is available; otherwise, no
     * bytes are read and 0 is returned.
     * 
     * This method simply performs in.read(b, off, len)
     * and returns the result.
     *
     * @param      b     the buffer into which the data is read.
     * @param      off   The start offset in the destination array
     *                   b.
     * @param      len   the maximum number of bytes read.
     * @return     the total number of bytes read into the buffer, or
     *             -1 if there is no more data because the end of
     *             the stream has been reached.
     * @exception  NullPointerException If b is null.
     * @exception  IndexOutOfBoundsException If off is negative,
     * len is negative, or len is greater than
     * b.length - off
     * @exception  IOException  if an I/O error occurs.
     * @see        java.io.FilterInputStream#in
     */
    public int read(byte[] b, int off, int len) throws IOException {
        int res = super.read(b, off, len);
        if (res > 0) {
            count += res;
            checkLimit();
        }
        return res;
    }
    /**
     * Returns, whether this stream is already closed.
     * @return True, if the stream is closed, otherwise false.
     * @throws IOException An I/O error occurred.
     */
    public boolean isClosed() throws IOException {
        return closed;
    }
    /**
     * Closes this input stream and releases any system resources
     * associated with the stream.
     * This
     * method simply performs in.close().
     *
     * @exception  IOException  if an I/O error occurs.
     * @see        java.io.FilterInputStream#in
     */
    public void close() throws IOException {
        closed = true;
        super.close();
    }
}