Devolus
Devolus

Reputation: 22084

reset() on Inputstream without mark()

According to this documentation it says that:

void reset()

Repositions this stream to the position at the time the mark method was last called on this input stream.

But what happens if mark() was never called? Will it reset to the beginning of the stream (which is what I want) or will it be undefined? Also when I look at the documentation for markSupported() it says:

Tests if this input stream supports the mark and reset methods.

So this tests for reset as well, which indicates that reset might also not be supported. Is it safer in this case if I just close and reopen the stream in my own reset code?

Upvotes: 1

Views: 2186

Answers (2)

Harald K
Harald K

Reputation: 27084

The behavior of reset() without calling mark() isn't very stricly specified, but from the JavaDoc:

The general contract of reset is:

  • If the method markSupported returns true, then:

  • If the method mark has not been called since the stream was created, or the number of bytes read from the stream since mark was last called is larger than the argument to mark at that last call, then an IOException might be thrown.

  • If such an IOException is not thrown, then the stream is reset to a state such that all the bytes read since the most recent call to mark (or since the start of the file, if mark has not been called) will be resupplied to subsequent callers of the read method, followed by any bytes that otherwise would have been the next input data as of the time of the call to reset.

Upvotes: 2

ig0774
ig0774

Reputation: 41257

The documentation provides an answer; unfortunately, it is not an unambiguous answer:

The general contract of reset is:

If the method markSupported returns true, then:

  • If the method mark has not been called since the stream was created, or the number of bytes read from the stream since mark was last called is larger than the argument to mark at that last call, then an IOException might be thrown.

  • If such an IOException is not thrown, then the stream is reset to a state such that all the bytes read since the most recent call to mark (or since the start of the file, if mark has not been called) will be resupplied to subsequent callers of the read method, followed by any bytes that otherwise would have been the next input data as of the time of the call to reset.

If the method markSupported returns false, then:

  • The call to reset may throw an IOException.

  • If an IOException 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 read method depend on the particular type of the input stream.

In other words, if markSupported() returns true then the stream can either throw an IOException or behave as you want it to. If markSupported() returns false then it will either throw an exception or behave in an implementation-specific way.

In short, the interface contract makes no guarantee that the implementation will behave as you want it to. The safest thing seems to be to check for markSupported() and set a mark at the beginning of the input stream, if it is supported. If it is not supported, you need to either experiment to ensure the operation functions as expected or devise a means of recreating the stream.

Upvotes: 2

Related Questions