/** Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.*********************/package java.io;/*** A <code>PushbackInputStream</code> adds* functionality to another input stream, namely* the ability to "push back" or "unread" bytes,* by storing pushed-back bytes in an internal buffer.* This is useful in situations where* it is convenient for a fragment of code* to read an indefinite number of data bytes* that are delimited by a particular byte* value; after reading the terminating byte,* the code fragment can "unread" it, so that* the next read operation on the input stream* will reread the byte that was pushed back.* For example, bytes representing the characters* constituting an identifier might be terminated* by a byte representing an operator character;* a method whose job is to read just an identifier* can read until it sees the operator and* then push the operator back to be re-read.** @author David Connelly* @author Jonathan Payne* @since 1.0*/publicclass PushbackInputStream extends FilterInputStream {/*** The pushback buffer.* @since 1.1*/protected byte[] buf;/*** The position within the pushback buffer from which the next byte will* be read. When the buffer is empty, <code>pos</code> is equal to* <code>buf.length</code>; when the buffer is full, <code>pos</code> is* equal to zero.** @since 1.1*/protected int pos;/*** Check to make sure that this stream has not been closed*/private void ensureOpen() throws IOException {if (in == null)throw new IOException("Stream closed");}/*** Creates a <code>PushbackInputStream</code>* with a pushback buffer of the specified <code>size</code>,* and saves its argument, the input stream* <code>in</code>, for later use. Initially,* the pushback buffer is empty.** @param in the input stream from which bytes will be read.* @param size the size of the pushback buffer.* @exception IllegalArgumentException if {@code size <= 0}* @since 1.1*/public PushbackInputStream(InputStream in, int size) {super(in);if (size <= 0) {throw new IllegalArgumentException("size <= 0");}this.buf = new byte[size];this.pos = size;}/*** Creates a <code>PushbackInputStream</code>* with a 1-byte pushback buffer, and saves its argument, the input stream* <code>in</code>, for later use. Initially,* the pushback buffer is empty.** @param in the input stream from which bytes will be read.*/public PushbackInputStream(InputStream in) {this(in, 1);}/*** Reads the next byte of data from this input stream. The value* byte is returned as an <code>int</code> in the range* <code>0</code> to <code>255</code>. If no byte is available* because the end of the stream has been reached, the value* <code>-1</code> is returned. This method blocks until input data* is available, the end of the stream is detected, or an exception* is thrown.** <p> This method returns the most recently pushed-back byte, if there is* one, and otherwise calls the <code>read</code> method of its underlying* input stream and returns whatever value that method returns.** @return the next byte of data, or <code>-1</code> if the end of the* stream has been reached.* @exception IOException if this input stream has been closed by* invoking its {@link #close()} method,* or an I/O error occurs.* @see java.io.InputStream#read()*/public int read() throws IOException {ensureOpen();if (pos < buf.length) {return buf[pos++] & 0xff;}return super.read();}/*** Reads up to <code>len</code> bytes of data from this input stream into* an array of bytes. This method first reads any pushed-back bytes; after* that, if fewer than <code>len</code> bytes have been read then it* reads from the underlying input stream. If <code>len</code> is not zero, the method* blocks until at least 1 byte of input is available; otherwise, no* bytes are read and <code>0</code> is returned.** @param b the buffer into which the data is read.* @param off the start offset in the destination array <code>b</code>* @param len the maximum number of bytes read.* @return the total number of bytes read into the buffer, or* <code>-1</code> if there is no more data because the end of* the stream has been reached.* @exception NullPointerException If <code>b</code> is <code>null</code>.* @exception IndexOutOfBoundsException If <code>off</code> is negative,* <code>len</code> is negative, or <code>len</code> is greater than* <code>b.length - off</code>* @exception IOException if this input stream has been closed by* invoking its {@link #close()} method,* or an I/O error occurs.* @see java.io.InputStream#read(byte[], int, int)*/public int read(byte[] b, int off, int len) throws IOException {ensureOpen();if (b == null) {throw new NullPointerException();} else if (off < 0 || len < 0 || len > b.length - off) {throw new IndexOutOfBoundsException();} else if (len == 0) {return 0;}int avail = buf.length - pos;if (avail > 0) {if (len < avail) {avail = len;}System.arraycopy(buf, pos, b, off, avail);pos += avail;off += avail;len -= avail;}if (len > 0) {len = super.read(b, off, len);if (len == -1) {return avail == 0 ? -1 : avail;}return avail + len;}return avail;}/*** Pushes back a byte by copying it to the front of the pushback buffer.* After this method returns, the next byte to be read will have the value* <code>(byte)b</code>.** @param b the <code>int</code> value whose low-order* byte is to be pushed back.* @exception IOException If there is not enough room in the pushback* buffer for the byte, or this input stream has been closed by* invoking its {@link #close()} method.*/public void unread(int b) throws IOException {ensureOpen();if (pos == 0) {throw new IOException("Push back buffer is full");}buf[--pos] = (byte)b;}/*** Pushes back a portion of an array of bytes by copying it to the front* of the pushback buffer. After this method returns, the next byte to be* read will have the value <code>b[off]</code>, the byte after that will* have the value <code>b[off+1]</code>, and so forth.** @param b the byte array to push back.* @param off the start offset of the data.* @param len the number of bytes to push back.* @exception IOException If there is not enough room in the pushback* buffer for the specified number of bytes,* or this input stream has been closed by* invoking its {@link #close()} method.* @since 1.1*/public void unread(byte[] b, int off, int len) throws IOException {ensureOpen();if (len > pos) {throw new IOException("Push back buffer is full");}pos -= len;System.arraycopy(b, off, buf, pos, len);}/*** Pushes back an array of bytes by copying it to the front of the* pushback buffer. After this method returns, the next byte to be read* will have the value <code>b[0]</code>, the byte after that will have the* value <code>b[1]</code>, and so forth.** @param b the byte array to push back* @exception IOException If there is not enough room in the pushback* buffer for the specified number of bytes,* or this input stream has been closed by* invoking its {@link #close()} method.* @since 1.1*/public void unread(byte[] b) throws IOException {unread(b, 0, b.length);}/*** Returns an estimate of the number of bytes that can be read (or* skipped over) from this input stream without blocking by the next* invocation of a method for this input stream. The next invocation might be* the same thread or another thread. A single read or skip of this* many bytes will not block, but may read or skip fewer bytes.** <p> The method returns the sum of the number of bytes that have been* pushed back and the value returned by {@link* java.io.FilterInputStream#available available}.** @return the number of bytes that can be read (or skipped over) from* the input stream without blocking.* @exception IOException if this input stream has been closed by* invoking its {@link #close()} method,* or an I/O error occurs.* @see java.io.FilterInputStream#in* @see java.io.InputStream#available()*/public int available() throws IOException {ensureOpen();int n = buf.length - pos;int avail = super.available();return n > (Integer.MAX_VALUE - avail)? Integer.MAX_VALUE: n + avail;}/*** Skips over and discards <code>n</code> bytes of data from this* input stream. The <code>skip</code> method may, for a variety of* reasons, end up skipping over some smaller number of bytes,* possibly zero. If <code>n</code> is negative, no bytes are skipped.** <p> The <code>skip</code> method of <code>PushbackInputStream</code>* first skips over the bytes in the pushback buffer, if any. It then* calls the <code>skip</code> method of the underlying input stream if* more bytes need to be skipped. The actual number of bytes skipped* is returned.** @param n {@inheritDoc}* @return {@inheritDoc}* @throws IOException if the stream has been closed by* invoking its {@link #close()} method,* {@code in.skip(n)} throws an IOException,* or an I/O error occurs.* @see java.io.FilterInputStream#in* @see java.io.InputStream#skip(long n)* @since 1.2*/public long skip(long n) throws IOException {ensureOpen();if (n <= 0) {return 0;}long pskip = buf.length - pos;if (pskip > 0) {if (n < pskip) {pskip = n;}pos += pskip;n -= pskip;}if (n > 0) {pskip += super.skip(n);}return pskip;}/*** Tests if this input stream supports the <code>mark</code> and* <code>reset</code> methods, which it does not.** @return <code>false</code>, since this class does not support the* <code>mark</code> and <code>reset</code> methods.* @see java.io.InputStream#mark(int)* @see java.io.InputStream#reset()*/public boolean markSupported() {return false;}/*** Marks the current position in this input stream.** <p> The <code>mark</code> method of <code>PushbackInputStream</code>* does nothing.** @param readlimit the maximum limit of bytes that can be read before* the mark position becomes invalid.* @see java.io.InputStream#reset()*/public synchronized void mark(int readlimit) {}/*** Repositions this stream to the position at the time the* <code>mark</code> method was last called on this input stream.** <p> The method <code>reset</code> for class* <code>PushbackInputStream</code> does nothing except throw an* <code>IOException</code>.** @exception IOException if this method is invoked.* @see java.io.InputStream#mark(int)* @see java.io.IOException*/public synchronized void reset() throws IOException {throw new IOException("mark/reset not supported");}/*** Closes this input stream and releases any system resources* associated with the stream.* Once the stream has been closed, further read(), unread(),* available(), reset(), or skip() invocations will throw an IOException.* Closing a previously closed stream has no effect.** @exception IOException if an I/O error occurs.*/public synchronized void close() throws IOException {if (in == null)return;in.close();in = null;buf = null;}}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。