jtulach@118: /* jtulach@118: * Copyright (c) 1994, 2006, Oracle and/or its affiliates. All rights reserved. jtulach@118: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. jtulach@118: * jtulach@118: * This code is free software; you can redistribute it and/or modify it jtulach@118: * under the terms of the GNU General Public License version 2 only, as jtulach@118: * published by the Free Software Foundation. Oracle designates this jtulach@118: * particular file as subject to the "Classpath" exception as provided jtulach@118: * by Oracle in the LICENSE file that accompanied this code. jtulach@118: * jtulach@118: * This code is distributed in the hope that it will be useful, but WITHOUT jtulach@118: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or jtulach@118: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License jtulach@118: * version 2 for more details (a copy is included in the LICENSE file that jtulach@118: * accompanied this code). jtulach@118: * jtulach@118: * You should have received a copy of the GNU General Public License version jtulach@118: * 2 along with this work; if not, write to the Free Software Foundation, jtulach@118: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. jtulach@118: * jtulach@118: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA jtulach@118: * or visit www.oracle.com if you need additional information or have any jtulach@118: * questions. jtulach@118: */ jtulach@118: jtulach@118: package java.io; jtulach@118: jtulach@118: /** jtulach@118: * This abstract class is the superclass of all classes representing jtulach@118: * an input stream of bytes. jtulach@118: * jtulach@118: *
Applications that need to define a subclass of InputStream
jtulach@118: * must always provide a method that returns the next byte of input.
jtulach@118: *
jtulach@118: * @author Arthur van Hoff
jtulach@118: * @see java.io.BufferedInputStream
jtulach@118: * @see java.io.ByteArrayInputStream
jtulach@118: * @see java.io.DataInputStream
jtulach@118: * @see java.io.FilterInputStream
jtulach@118: * @see java.io.InputStream#read()
jtulach@118: * @see java.io.OutputStream
jtulach@118: * @see java.io.PushbackInputStream
jtulach@118: * @since JDK1.0
jtulach@118: */
jtulach@118: public abstract class InputStream implements Closeable {
jtulach@118:
jtulach@118: // SKIP_BUFFER_SIZE is used to determine the size of skipBuffer
jtulach@118: private static final int SKIP_BUFFER_SIZE = 2048;
jtulach@118: // skipBuffer is initialized in skip(long), if needed.
jtulach@118: private static byte[] skipBuffer;
jtulach@118:
jtulach@118: /**
jtulach@118: * Reads the next byte of data from the input stream. The value byte is
jtulach@118: * returned as an int
in the range 0
to
jtulach@118: * 255
. If no byte is available because the end of the stream
jtulach@118: * has been reached, the value -1
is returned. This method
jtulach@118: * blocks until input data is available, the end of the stream is detected,
jtulach@118: * or an exception is thrown.
jtulach@118: *
jtulach@118: *
A subclass must provide an implementation of this method.
jtulach@118: *
jtulach@118: * @return the next byte of data, or -1
if the end of the
jtulach@118: * stream is reached.
jtulach@118: * @exception IOException if an I/O error occurs.
jtulach@118: */
jtulach@118: public abstract int read() throws IOException;
jtulach@118:
jtulach@118: /**
jtulach@118: * Reads some number of bytes from the input stream and stores them into
jtulach@118: * the buffer array b
. The number of bytes actually read is
jtulach@118: * returned as an integer. This method blocks until input data is
jtulach@118: * available, end of file is detected, or an exception is thrown.
jtulach@118: *
jtulach@118: *
If the length of b
is zero, then no bytes are read and
jtulach@118: * 0
is returned; otherwise, there is an attempt to read at
jtulach@118: * least one byte. If no byte is available because the stream is at the
jtulach@118: * end of the file, the value -1
is returned; otherwise, at
jtulach@118: * least one byte is read and stored into b
.
jtulach@118: *
jtulach@118: *
The first byte read is stored into element b[0]
, the
jtulach@118: * next one into b[1]
, and so on. The number of bytes read is,
jtulach@118: * at most, equal to the length of b
. Let k be the
jtulach@118: * number of bytes actually read; these bytes will be stored in elements
jtulach@118: * b[0]
through b[
k-1]
,
jtulach@118: * leaving elements b[
k]
through
jtulach@118: * b[b.length-1]
unaffected.
jtulach@118: *
jtulach@118: *
The read(b)
method for class InputStream
jtulach@118: * has the same effect as:
read(b, 0, b.length)
jtulach@118: *
jtulach@118: * @param b the buffer into which the data is read.
jtulach@118: * @return the total number of bytes read into the buffer, or
jtulach@118: * -1
if there is no more data because the end of
jtulach@118: * the stream has been reached.
jtulach@118: * @exception IOException If the first byte cannot be read for any reason
jtulach@118: * other than the end of the file, if the input stream has been closed, or
jtulach@118: * if some other I/O error occurs.
jtulach@118: * @exception NullPointerException if b
is null
.
jtulach@118: * @see java.io.InputStream#read(byte[], int, int)
jtulach@118: */
jtulach@118: public int read(byte b[]) throws IOException {
jtulach@118: return read(b, 0, b.length);
jtulach@118: }
jtulach@118:
jtulach@118: /**
jtulach@118: * Reads up to len
bytes of data from the input stream into
jtulach@118: * an array of bytes. An attempt is made to read as many as
jtulach@118: * len
bytes, but a smaller number may be read.
jtulach@118: * The number of bytes actually read is returned as an integer.
jtulach@118: *
jtulach@118: * This method blocks until input data is available, end of file is jtulach@118: * detected, or an exception is thrown. jtulach@118: * jtulach@118: *
If len
is zero, then no bytes are read and
jtulach@118: * 0
is returned; otherwise, there is an attempt to read at
jtulach@118: * least one byte. If no byte is available because the stream is at end of
jtulach@118: * file, the value -1
is returned; otherwise, at least one
jtulach@118: * byte is read and stored into b
.
jtulach@118: *
jtulach@118: *
The first byte read is stored into element b[off]
, the
jtulach@118: * next one into b[off+1]
, and so on. The number of bytes read
jtulach@118: * is, at most, equal to len
. Let k be the number of
jtulach@118: * bytes actually read; these bytes will be stored in elements
jtulach@118: * b[off]
through b[off+
k-1]
,
jtulach@118: * leaving elements b[off+
k]
through
jtulach@118: * b[off+len-1]
unaffected.
jtulach@118: *
jtulach@118: *
In every case, elements b[0]
through
jtulach@118: * b[off]
and elements b[off+len]
through
jtulach@118: * b[b.length-1]
are unaffected.
jtulach@118: *
jtulach@118: *
The read(b,
off,
len)
method
jtulach@118: * for class InputStream
simply calls the method
jtulach@118: * read()
repeatedly. If the first such call results in an
jtulach@118: * IOException
, that exception is returned from the call to
jtulach@118: * the read(b,
off,
len)
method. If
jtulach@118: * any subsequent call to read()
results in a
jtulach@118: * IOException
, the exception is caught and treated as if it
jtulach@118: * were end of file; the bytes read up to that point are stored into
jtulach@118: * b
and the number of bytes read before the exception
jtulach@118: * occurred is returned. The default implementation of this method blocks
jtulach@118: * until the requested amount of input data len
has been read,
jtulach@118: * end of file is detected, or an exception is thrown. Subclasses are encouraged
jtulach@118: * to provide a more efficient implementation of this method.
jtulach@118: *
jtulach@118: * @param b the buffer into which the data is read.
jtulach@118: * @param off the start offset in array b
jtulach@118: * at which the data is written.
jtulach@118: * @param len the maximum number of bytes to read.
jtulach@118: * @return the total number of bytes read into the buffer, or
jtulach@118: * -1
if there is no more data because the end of
jtulach@118: * the stream has been reached.
jtulach@118: * @exception IOException If the first byte cannot be read for any reason
jtulach@118: * other than end of file, or if the input stream has been closed, or if
jtulach@118: * some other I/O error occurs.
jtulach@118: * @exception NullPointerException If b
is null
.
jtulach@118: * @exception IndexOutOfBoundsException If off
is negative,
jtulach@118: * len
is negative, or len
is greater than
jtulach@118: * b.length - off
jtulach@118: * @see java.io.InputStream#read()
jtulach@118: */
jtulach@118: public int read(byte b[], int off, int len) throws IOException {
jtulach@118: if (b == null) {
jtulach@118: throw new NullPointerException();
jtulach@118: } else if (off < 0 || len < 0 || len > b.length - off) {
jtulach@118: throw new IndexOutOfBoundsException();
jtulach@118: } else if (len == 0) {
jtulach@118: return 0;
jtulach@118: }
jtulach@118:
jtulach@118: int c = read();
jtulach@118: if (c == -1) {
jtulach@118: return -1;
jtulach@118: }
jtulach@118: b[off] = (byte)c;
jtulach@118:
jtulach@118: int i = 1;
jtulach@118: try {
jtulach@118: for (; i < len ; i++) {
jtulach@118: c = read();
jtulach@118: if (c == -1) {
jtulach@118: break;
jtulach@118: }
jtulach@118: b[off + i] = (byte)c;
jtulach@118: }
jtulach@118: } catch (IOException ee) {
jtulach@118: }
jtulach@118: return i;
jtulach@118: }
jtulach@118:
jtulach@118: /**
jtulach@118: * Skips over and discards n
bytes of data from this input
jtulach@118: * stream. The skip
method may, for a variety of reasons, end
jtulach@118: * up skipping over some smaller number of bytes, possibly 0
.
jtulach@118: * This may result from any of a number of conditions; reaching end of file
jtulach@118: * before n
bytes have been skipped is only one possibility.
jtulach@118: * The actual number of bytes skipped is returned. If n
is
jtulach@118: * negative, no bytes are skipped.
jtulach@118: *
jtulach@118: *
The skip
method of this class creates a
jtulach@118: * byte array and then repeatedly reads into it until n
bytes
jtulach@118: * have been read or the end of the stream has been reached. Subclasses are
jtulach@118: * encouraged to provide a more efficient implementation of this method.
jtulach@118: * For instance, the implementation may depend on the ability to seek.
jtulach@118: *
jtulach@118: * @param n the number of bytes to be skipped.
jtulach@118: * @return the actual number of bytes skipped.
jtulach@118: * @exception IOException if the stream does not support seek,
jtulach@118: * or if some other I/O error occurs.
jtulach@118: */
jtulach@118: public long skip(long n) throws IOException {
jtulach@118:
jtulach@118: long remaining = n;
jtulach@118: int nr;
jtulach@118: if (skipBuffer == null)
jtulach@118: skipBuffer = new byte[SKIP_BUFFER_SIZE];
jtulach@118:
jtulach@118: byte[] localSkipBuffer = skipBuffer;
jtulach@118:
jtulach@118: if (n <= 0) {
jtulach@118: return 0;
jtulach@118: }
jtulach@118:
jtulach@118: while (remaining > 0) {
jtulach@118: nr = read(localSkipBuffer, 0,
jtulach@118: (int) Math.min(SKIP_BUFFER_SIZE, remaining));
jtulach@118: if (nr < 0) {
jtulach@118: break;
jtulach@118: }
jtulach@118: remaining -= nr;
jtulach@118: }
jtulach@118:
jtulach@118: return n - remaining;
jtulach@118: }
jtulach@118:
jtulach@118: /**
jtulach@118: * Returns an estimate of the number of bytes that can be read (or
jtulach@118: * skipped over) from this input stream without blocking by the next
jtulach@118: * invocation of a method for this input stream. The next invocation
jtulach@118: * might be the same thread or another thread. A single read or skip of this
jtulach@118: * many bytes will not block, but may read or skip fewer bytes.
jtulach@118: *
jtulach@118: *
Note that while some implementations of {@code InputStream} will return jtulach@118: * the total number of bytes in the stream, many will not. It is jtulach@118: * never correct to use the return value of this method to allocate jtulach@118: * a buffer intended to hold all data in this stream. jtulach@118: * jtulach@118: *
A subclass' implementation of this method may choose to throw an jtulach@118: * {@link IOException} if this input stream has been closed by jtulach@118: * invoking the {@link #close()} method. jtulach@118: * jtulach@118: *
The {@code available} method for class {@code InputStream} always jtulach@118: * returns {@code 0}. jtulach@118: * jtulach@118: *
This method should be overridden by subclasses. jtulach@118: * jtulach@118: * @return an estimate of the number of bytes that can be read (or skipped jtulach@118: * over) from this input stream without blocking or {@code 0} when jtulach@118: * it reaches the end of the input stream. jtulach@118: * @exception IOException if an I/O error occurs. jtulach@118: */ jtulach@118: public int available() throws IOException { jtulach@118: return 0; jtulach@118: } jtulach@118: jtulach@118: /** jtulach@118: * Closes this input stream and releases any system resources associated jtulach@118: * with the stream. jtulach@118: * jtulach@118: *
The close
method of InputStream
does
jtulach@118: * nothing.
jtulach@118: *
jtulach@118: * @exception IOException if an I/O error occurs.
jtulach@118: */
jtulach@118: public void close() throws IOException {}
jtulach@118:
jtulach@118: /**
jtulach@118: * Marks the current position in this input stream. A subsequent call to
jtulach@118: * the reset
method repositions this stream at the last marked
jtulach@118: * position so that subsequent reads re-read the same bytes.
jtulach@118: *
jtulach@118: *
The readlimit
arguments tells this input stream to
jtulach@118: * allow that many bytes to be read before the mark position gets
jtulach@118: * invalidated.
jtulach@118: *
jtulach@118: *
The general contract of mark
is that, if the method
jtulach@118: * markSupported
returns true
, the stream somehow
jtulach@118: * remembers all the bytes read after the call to mark
and
jtulach@118: * stands ready to supply those same bytes again if and whenever the method
jtulach@118: * reset
is called. However, the stream is not required to
jtulach@118: * remember any data at all if more than readlimit
bytes are
jtulach@118: * read from the stream before reset
is called.
jtulach@118: *
jtulach@118: *
Marking a closed stream should not have any effect on the stream. jtulach@118: * jtulach@118: *
The mark
method of InputStream
does
jtulach@118: * nothing.
jtulach@118: *
jtulach@118: * @param readlimit the maximum limit of bytes that can be read before
jtulach@118: * the mark position becomes invalid.
jtulach@118: * @see java.io.InputStream#reset()
jtulach@118: */
jtulach@118: public synchronized void mark(int readlimit) {}
jtulach@118:
jtulach@118: /**
jtulach@118: * Repositions this stream to the position at the time the
jtulach@118: * mark
method was last called on this input stream.
jtulach@118: *
jtulach@118: *
The general contract of reset
is:
jtulach@118: *
jtulach@118: *
markSupported
returns
jtulach@118: * true
, then:
jtulach@118: *
jtulach@118: * mark
has not been called since
jtulach@118: * the stream was created, or the number of bytes read from the stream
jtulach@118: * since mark
was last called is larger than the argument
jtulach@118: * to mark
at that last call, then an
jtulach@118: * IOException
might be thrown.
jtulach@118: *
jtulach@118: * IOException
is not thrown, then the
jtulach@118: * stream is reset to a state such that all the bytes read since the
jtulach@118: * most recent call to mark
(or since the start of the
jtulach@118: * file, if mark
has not been called) will be resupplied
jtulach@118: * to subsequent callers of the read
method, followed by
jtulach@118: * any bytes that otherwise would have been the next input data as of
jtulach@118: * the time of the call to reset
. markSupported
returns
jtulach@118: * false
, then:
jtulach@118: *
jtulach@118: * reset
may throw an
jtulach@118: * IOException
.
jtulach@118: *
jtulach@118: * IOException
is not thrown, then the stream
jtulach@118: * is reset to a fixed state that depends on the particular type of the
jtulach@118: * input stream and how it was created. The bytes that will be supplied
jtulach@118: * to subsequent callers of the read
method depend on the
jtulach@118: * particular type of the input stream. The method reset
for class InputStream
jtulach@118: * does nothing except throw an IOException
.
jtulach@118: *
jtulach@118: * @exception IOException if this stream has not been marked or if the
jtulach@118: * mark has been invalidated.
jtulach@118: * @see java.io.InputStream#mark(int)
jtulach@118: * @see java.io.IOException
jtulach@118: */
jtulach@118: public synchronized void reset() throws IOException {
jtulach@118: throw new IOException("mark/reset not supported");
jtulach@118: }
jtulach@118:
jtulach@118: /**
jtulach@118: * Tests if this input stream supports the mark
and
jtulach@118: * reset
methods. Whether or not mark
and
jtulach@118: * reset
are supported is an invariant property of a
jtulach@118: * particular input stream instance. The markSupported
method
jtulach@118: * of InputStream
returns false
.
jtulach@118: *
jtulach@118: * @return true
if this stream instance supports the mark
jtulach@118: * and reset methods; false
otherwise.
jtulach@118: * @see java.io.InputStream#mark(int)
jtulach@118: * @see java.io.InputStream#reset()
jtulach@118: */
jtulach@118: public boolean markSupported() {
jtulach@118: return false;
jtulach@118: }
jtulach@118:
jtulach@118: }