java request getinputstream_浅谈request.getinputstream只能读取一次的问题

首先,我们复习一下inputstream read方法的基础知识,

java inputstream read方法内部有一个,postion,标志当前流读取到的位置,每读取一次,位置就会移动一次,如果读到最后,inputstream.read方法会返回-1,标志已经读取完了,如果想再次读取,可以调用inputstream.reset方法,position就会移动到上次调用mark的位置,mark默认是0,所以就能从头再读了。

当然,能否reset是有条件的,它取决于marksupported,marksupported() 方法返回是否可以mark/reset

我们再回头看request.getinputstream

request.getinputstream返回的值是servletinputstream,查看servletinputstream源码发现,没有重写reset方法,所以查看inputstream源码发现marksupported 返回false,并且reset方法,直接抛出异常。

inputstream.java

public boolean marksupported() {

return false;

}

public synchronized void reset() throws ioexception {

throw new ioexception("mark/reset not supported");

}

综上所述,在request.getinputstream读取一次后position到了文件末尾,第二次就读取不到数据,由于无法reset(),所以,request.getinputstream只能读取一次。

总结:

这个问题最根本还是对java io的read、reset方法的深入理解,尤其是read方法的内部实现原理。

附servletinputstream.java源码

/*

* 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.

*/

package javax.servlet;

import java.io.ioexception;

import java.io.inputstream;

/**

* provides an input stream for reading binary data from a client request,

* including an efficient readline method for reading data one line

* at a time. with some protocols, such as http post and put, a

* servletinputstream object can be used to read data sent from the

* client.

*

* a servletinputstream object is normally retrieved via the

* {@link servletrequest#getinputstream} method.

*

* this is an abstract class that a servlet container implements. subclasses of

* this class must implement the java.io.inputstream.read() method.

*

* @see servletrequest

*/

public abstract class servletinputstream extends inputstream {

/**

* does nothing, because this is an abstract class.

*/

protected servletinputstream() {

// noop

}

/**

* reads the input stream, one line at a time. starting at an offset, reads

* bytes into an array, until it reads a certain number of bytes or reaches

* a newline character, which it reads into the array as well.

*

* this method returns -1 if it reaches the end of the input stream before

* reading the maximum number of bytes.

*

* @param b

* an array of bytes into which data is read

* @param off

* an integer specifying the character at which this method

* begins reading

* @param len

* an integer specifying the maximum number of bytes to read

* @return an integer specifying the actual number of bytes read, or -1 if

* the end of the stream is reached

* @exception ioexception

* if an input or output exception has occurred

*/

public int readline(byte[] b, int off, int len) throws ioexception {

if (len <= 0) {

return 0;

}

int count = 0, c;

while ((c = read()) != -1) {

b[off++] = (byte) c;

count++;

if (c == '\n' || count == len) {

break;

}

}

return count > 0 ? count : -1;

}

/**

* returns true if all the data has been read from the stream,

* else false.

*

* @since servlet 3.1

*/

public abstract boolean isfinished();

/**

* returns true if data can be read without blocking, else

* false. if this method is called and returns false, the

* container will invoke {@link readlistener#ondataavailable()} when data is

* available.

*

* @since servlet 3.1

*/

public abstract boolean isready();

/**

* sets the {@link readlistener} for this {@link servletinputstream} and

* thereby switches to non-blocking io. it is only valid to switch to

* non-blocking io within async processing or http upgrade processing.

*

* @param listener the non-blocking io read listener

*

* @throws illegalstateexception if this method is called if neither

* async nor http upgrade is in progress or

* if the {@link readlistener} has already

* been set

* @throws nullpointerexception if listener is null

*

* @since servlet 3.1

*/

public abstract void setreadlistener(readlistener listener);

}

以上这篇浅谈request.getinputstream只能读取一次的问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持萬仟网。

希望与广大网友互动??

点此进行留言吧!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值