httpServletRequest中的流只能读取一次

  首先,进入javax.servlet.ServletInputStream类,该类继承了InputStream,从InputStream中调用了read方法,这里我们先看read的源码和注释

/** Reads up to len bytes of data from the input stream into an array of bytes. An *attempt is made to read as many as len bytes, but a smaller number may be read. The *number of bytes actually read is returned as an integer.
*This method blocks until input data is available, end of file is detected, or an *exception is thrown.
*If len is zero, then no bytes are read and 0 is returned; otherwise, there is an attempt *to read at least one byte. If no byte is available because the stream is at end of file, *the value -1 is returned; otherwise, at least one byte is read and stored into b.
*The first byte read is stored into element b[off], the next one into b[off+1], and so *on. The number of bytes read is, at most, equal to len. Let k be the number of bytes *actually read; these bytes will be stored in elements b[off] through b[off+k-1], leaving *elements b[off+k] through b[off+len-1] unaffected.
*In every case, elements b[0] through b[off] and elements b[off+len] through b[b.length-*1] are unaffected.
*The read(b, off, len) method for class InputStream simply calls the method read() *repeatedly. If the first such call results in an IOException, that exception is returned *from the call to the read(b, off, len) method. If any subsequent call to read() results *in a IOException, the exception is caught and treated as if it were end of file; the *bytes read up to that point are stored into b and the number of bytes read before the *exception occurred is returned. The default implementation of this method blocks until *the requested amount of input data len has been read, end of file is detected, or an *exception is thrown. Subclasses are encouraged to provide a more efficient *implementation of this method.
*Params:
*b – the buffer into which the data is read.
*off – the start offset in array b at which the data is written.
*len – the maximum number of bytes to read.
*Returns:
*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.
*Throws:
*IOException – If the first byte cannot be read for any reason other than end of file, or *if the input stream has been closed, or if some other I/O error occurs.
*NullPointerException – If b is null.
*IndexOutOfBoundsException – If off is negative, len is negative, or len is greater than *b.length - off
*See Also:
*read()
** /
public int read(byte b[], int off, int len) throws IOException {
        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 c = read();
        if (c == -1) {
            return -1;
        }
        b[off] = (byte)c;

        int i = 1;
        try {
            for (; i < len ; i++) {
                c = read();
                if (c == -1) {
                    break;
                }
                b[off + i] = (byte)c;
            }
        } catch (IOException ee) {
        }
        return i;
    }

从输入流读取一定数量的字节,存储到缓冲区中,如果已经到达流的末尾,没有更多的数据,则返回-1.

    InputStream中还有mark方法以及reset方法,mark用法用以标记输入流中的当前位置,之后调用reset方法时,将此流重新定位到该输入流的上一次调用mark的位置,mark的一般约定是,如果方法markSupported返回true,流将以某种方式记住调用mark后读取的所有字节,并随时准备在调用reset方法时再次提供相同的字节。但是,如果在调用reset之前从流中读取了超过readlimit的字节,则流根本不需要记住任何数据。

但是在InputStream中的markSupported方法直接返回了false以及reset方法直接抛出异常,看源码:


    /**
     * Repositions this stream to the position at the time the
     * <code>mark</code> method was last called on this input stream.
     *
     * <p> The general contract of <code>reset</code> is:
     *
     * <ul>
     * <li> If the method <code>markSupported</code> returns
     * <code>true</code>, then:
     *
     *     <ul><li> If the method <code>mark</code> has not been called since
     *     the stream was created, or the number of bytes read from the stream
     *     since <code>mark</code> was last called is larger than the argument
     *     to <code>mark</code> at that last call, then an
     *     <code>IOException</code> might be thrown.
     *
     *     <li> If such an <code>IOException</code> is not thrown, then the
     *     stream is reset to a state such that all the bytes read since the
     *     most recent call to <code>mark</code> (or since the start of the
     *     file, if <code>mark</code> has not been called) will be resupplied
     *     to subsequent callers of the <code>read</code> method, followed by
     *     any bytes that otherwise would have been the next input data as of
     *     the time of the call to <code>reset</code>. </ul>
     *
     * <li> If the method <code>markSupported</code> returns
     * <code>false</code>, then:
     *
     *     <ul><li> The call to <code>reset</code> may throw an
     *     <code>IOException</code>.
     *
     *     <li> If an <code>IOException</code> is not thrown, then the stream
     *     is reset to a fixed state that depends on the particular type of the
     *     input stream and how it was created. The bytes that will be supplied
     *     to subsequent callers of the <code>read</code> method depend on the
     *     particular type of the input stream. </ul></ul>
     *
     * <p>The method <code>reset</code> for class <code>InputStream</code>
     * does nothing except throw an <code>IOException</code>.
     *
     * @exception  IOException  if this stream has not been marked or if the
     *               mark has been invalidated.
     * @see     java.io.InputStream#mark(int)
     * @see     java.io.IOException
     */
    public synchronized void reset() throws IOException {
        throw new IOException("mark/reset not supported");
    }

    /**
     * Tests if this input stream supports the <code>mark</code> and
     * <code>reset</code> methods. Whether or not <code>mark</code> and
     * <code>reset</code> are supported is an invariant property of a
     * particular input stream instance. The <code>markSupported</code> method
     * of <code>InputStream</code> returns <code>false</code>.
     *
     * @return  <code>true</code> if this stream instance supports the mark
     *          and reset methods; <code>false</code> otherwise.
     * @see     java.io.InputStream#mark(int)
     * @see     java.io.InputStream#reset()
     */
    public boolean markSupported() {
        return false;
    }

由此可见,InputStream中不让我们重复读取输入流,只能读取一次。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值