浅谈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 pliance with the License. You may obtain a copy of the License at http://.apache./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 <code>readLine</code> method for reading data one line at a time. With some protocols, such as HTTP POST and PUT, a <code>ServletInputStream</code> object can be used to read data sent from the client. <p> A <code>ServletInputStream</code> object is normally retrieved via the {@link ServletRequest#getInputStream} method. <p> This is an abstract class that a servlet container implements. Subclasses of this class must implement the <code>java.io.InputStream.read()</code> 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. <p> 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 ourred / 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 <code>true</code> if all the data has been read from the stream, else <code>false</code>. @since Servlet 3.1 / public abstract boolean isFinished(); / Returns <code>true</code> if data can be read without blocking, else <code>false</code>. 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只能读取一次的问题就是长沙网络推广分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持狼蚁SEO。
编程语言
- 如何快速学会编程 如何快速学会ug编程
- 免费学编程的app 推荐12个免费学编程的好网站
- 电脑怎么编程:电脑怎么编程网咯游戏菜单图标
- 如何写代码新手教学 如何写代码新手教学手机
- 基础编程入门教程视频 基础编程入门教程视频华
- 编程演示:编程演示浦丰投针过程
- 乐高编程加盟 乐高积木编程加盟
- 跟我学plc编程 plc编程自学入门视频教程
- ug编程成航林总 ug编程实战视频
- 孩子学编程的好处和坏处
- 初学者学编程该从哪里开始 新手学编程从哪里入
- 慢走丝编程 慢走丝编程难学吗
- 国内十强少儿编程机构 中国少儿编程机构十强有
- 成人计算机速成培训班 成人计算机速成培训班办
- 孩子学编程网上课程哪家好 儿童学编程比较好的
- 代码编程教学入门软件 代码编程教程