BufferedInputStream类中的mark(int readlimit)方法释疑

先看官方API文档

mark

public void mark(int readlimit)
See the general contract of the mark method of InputStream.

Overrides:
mark in class FilterInputStream
Parameters:
readlimit - the maximum limit of bytes that can be read before the mark position becomes invalid.
See Also:
reset()

好吧,它让继续看父类的

mark

public void mark(int readlimit)
Marks the current position in this input stream. A subsequent call to the reset method repositions this stream at the last marked position so that subsequent reads re-read the same bytes.

The readlimit arguments tells this input stream to allow that many bytes to be read before the mark position gets invalidated.

The general contract of mark is that, if the method markSupported returnstrue, the stream somehow remembers all the bytes read after the call tomark and stands ready to supply those same bytes again if and whenever the methodreset is called. However, the stream is not requiredto remember any data at all if more than readlimit bytes are read from the stream beforereset is called.

Marking a closed stream should not have any effect on the stream.

The mark method of InputStream does nothing.

Parameters:
readlimit - the maximum limit of bytes that can be read before the mark position becomes invalid.
See Also:
reset()

         根据JAVA官方文档的描述,mark(int readlimit)方法表示,标记当前位置,并保证在mark以后最多可以读取readlimit字节数据,mark标记仍有效。如果在mark后读取超过readlimit字节数据,mark标记就会失效,调用reset()方法会有异常。

      但实际的运行情况却和JAVA文档中的描述并不完全相符。 很多情况下在BufferedInputStream类中调用mark(int readlimit)方法后,即使读取超过readlimit字节的数据,mark标记仍有效,仍然能正确调用reset方法重置。看来那个is not required还别有深意,不需要可不等于一定不,看来还有别的条件限制。

      事实上,mark在JAVA中的实现是和缓冲区相关的。只要缓冲区够大,mark后读取的数据没有超出缓冲区的大小,mark标记就不会失效。如果不够大,mark后又读取了大量的数据,导致缓冲区更新,原来标记的位置自然找不到了。

      同样的,在调用mark(int readlimit)方法时,如果readlimit大于BufferedInputStream类缓冲区的大小,缓冲区会被扩大,那mark后最多就可以读readlimit字节。
    
        简言之,BufferedInputStream类调用mark(int readlimit)方法后读取多少字节标记才失效,是取readlimit和BufferedInputStream类的缓冲区大小两者中的最大值,而并非完全由readlimit确定。这个在JAVA文档中是没有提到的。

      因此,mark后读取多少字节才失效,并不完全由readlimit参数确定,也和BufferedInputStream类的缓冲区大小有关。 如果BufferedInputStream类的缓冲区大小大于readlimit,在mark以后只有读取超过缓冲区大小的数据,mark标记才会失效。

      读者可以在创建BufferedInputStream对象的时候用其第二个指定缓冲区大小的构造函数来自己做实验,自然就明朗了

你可能感兴趣的:(java,Stream,api,文档,input,Parameters)