Name: rmT116609 Date: 08/16/2004
A DESCRIPTION OF THE PROBLEM :
In various java.io and java.nio classes, for the bulk read methods (e.g.,
read(byte[]), read(ByteBuffer), the return value descriptions, especially
regarding return -1 at end-of-stream, are ambiguous and seem to specify
the opposite of what is intended and implemented (if any bytes are read,
the number of bytes is always returned).
THE PROBLEM:
Consider java.nio.channels.ReadableByteChannel.read(ByteBuffer). Its
method descriptions says:
...
Returns:
The number of bytes read, possibly zero, or -1 if the channel has reached
end-of-stream
Consider this case:
- The channel was not at the end of the stream at the beginning of the call,
- several bytes were read during the call, and
- the channel is at the end of the stream at the end of the call .
What is the the return value?
The documentation says "... -1 _if_ the channel has reached end-of-stream."
The channel has reached the end, so it seems that the method must return -1.
However, that does not seem to be the intent.
Returning -1 in that case would mean that a caller couldn't know how many
bytes were read except by recording the state (the position) of the ByteBuffer
before the call and comparing the state afterwards to the previous state.
Consider java.io.InputStream.read(byte[]): There would be
no way for the caller to know how many bytes were read into the array.
Additionally, what the wording says doesn' t match the implementations.
Note that in the case of ReadableByteChannel, the return value description is
the only documentation of the -1 return value. (For some other classes, the
method description gives a better description. For example,
InputStream.read(byte) mentions:
If no byte is available because the stream is at end of file, the value -1 is
returned"
That is, it doesn't just say "if at end then return value will be -1"; it says "if at end
and byte count is 0 then return value will be -1."
There problem is how the descriptions are worded:
1. The wording "has reached" is ambiguous regarding when the end was
reached. The author might have been thinking about
before the call. However, since the wording "the number of bytes read"
clearly refers to actions during the call, that fact that the "has reached" is
adjacent strongly implies that it also refers to during (at the end of) the call.
Additionally, just the fact that it's a value returned at the end of the method's
execution strongly implies that the default time (for interpreting verbs) is at
the end of the method.
2. The wording of the condition isn't quite right. Recall the wording:
The number of bytes read, possibly zero, or -1 if the channel has reached
end-of-stream
Neither this interpretation:
if at end then
result == -1 is true
else
result == count is true
end if
nor this one:
if at end then
result == -1 or result == count is true
else
result == count is true
reflects the intent.
POSSIBLE SOLUTIONS:
The wording should clearly and (reasonably) unambiguously document the
intended contract and actual implementations.
Perhaps instead of:
... -1 if the channel has reached end-of-stream
it could say:
... -1 if no bytes (or characters or whatever) were read because the channel
has reached end-of-stream
(ByteArrayInputStream.read(byte[], int, int) and several other methods are
described with wording like that.
INSTANCES OF THE PROBLEM:
Base classes/interfaces:
1. java.io.InputStream.read(byte[])
2. java.io.InputStream.read(byte[], int, int)
3. java.io.Reader.read(char[])
4. java.io.Reader.read(char[], int, int)
5. java.nio.ReadableByteChannel(ByteBuffer)
6. java.lang.Readable.read(CharBuffer)
Classes whose documentation isn't inherited from the base classes/
interfaces:
7. BufferedInputStream
8. BufferedReader
9. ByteArrayInputStream
10. DataInputStream
-- (not FileInputStream - says "no more data because ... end")
-- (not FilterInputStream - says "no more data because ... end")
11. InputStreamReader
12. LineNumberInputStream
(maybe not LineNumberReader - says " end ... _already_ ... reached"
13. ObjectInputStream
-- (not PipedInputStream - says "no more data because...")
-- (not PipedReader- says "no more data because...")
-- (not PushbackInputStream - says "no more data because...")
-- (not RandomAccessFile - says "no more data because...")
14. SequenceInputStream
-- (not StringBufferInputStream - says "no more data because...")
15. StringReader
16. ScatteringByteChannel
17. CharBuffer.read(CharBuffer)
18. CheckedInputStream
19. GZipInputStream
20. InflaterInputStream
21. ZipInputStream
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
See Description section.
ACTUAL -
See Description section.
URL OF FAULTY DOCUMENTATION :
http://java.sun.com/j2se/1.5.0/docs/api/java/nio/channels/ReadableByteChannel.html#read(java.nio.ByteBuffer)
(Incident Review ID: 296819)
======================================================================
A DESCRIPTION OF THE PROBLEM :
In various java.io and java.nio classes, for the bulk read methods (e.g.,
read(byte[]), read(ByteBuffer), the return value descriptions, especially
regarding return -1 at end-of-stream, are ambiguous and seem to specify
the opposite of what is intended and implemented (if any bytes are read,
the number of bytes is always returned).
THE PROBLEM:
Consider java.nio.channels.ReadableByteChannel.read(ByteBuffer). Its
method descriptions says:
...
Returns:
The number of bytes read, possibly zero, or -1 if the channel has reached
end-of-stream
Consider this case:
- The channel was not at the end of the stream at the beginning of the call,
- several bytes were read during the call, and
- the channel is at the end of the stream at the end of the call .
What is the the return value?
The documentation says "... -1 _if_ the channel has reached end-of-stream."
The channel has reached the end, so it seems that the method must return -1.
However, that does not seem to be the intent.
Returning -1 in that case would mean that a caller couldn't know how many
bytes were read except by recording the state (the position) of the ByteBuffer
before the call and comparing the state afterwards to the previous state.
Consider java.io.InputStream.read(byte[]): There would be
no way for the caller to know how many bytes were read into the array.
Additionally, what the wording says doesn' t match the implementations.
Note that in the case of ReadableByteChannel, the return value description is
the only documentation of the -1 return value. (For some other classes, the
method description gives a better description. For example,
InputStream.read(byte) mentions:
If no byte is available because the stream is at end of file, the value -1 is
returned"
That is, it doesn't just say "if at end then return value will be -1"; it says "if at end
and byte count is 0 then return value will be -1."
There problem is how the descriptions are worded:
1. The wording "has reached" is ambiguous regarding when the end was
reached. The author might have been thinking about
before the call. However, since the wording "the number of bytes read"
clearly refers to actions during the call, that fact that the "has reached" is
adjacent strongly implies that it also refers to during (at the end of) the call.
Additionally, just the fact that it's a value returned at the end of the method's
execution strongly implies that the default time (for interpreting verbs) is at
the end of the method.
2. The wording of the condition isn't quite right. Recall the wording:
The number of bytes read, possibly zero, or -1 if the channel has reached
end-of-stream
Neither this interpretation:
if at end then
result == -1 is true
else
result == count is true
end if
nor this one:
if at end then
result == -1 or result == count is true
else
result == count is true
reflects the intent.
POSSIBLE SOLUTIONS:
The wording should clearly and (reasonably) unambiguously document the
intended contract and actual implementations.
Perhaps instead of:
... -1 if the channel has reached end-of-stream
it could say:
... -1 if no bytes (or characters or whatever) were read because the channel
has reached end-of-stream
(ByteArrayInputStream.read(byte[], int, int) and several other methods are
described with wording like that.
INSTANCES OF THE PROBLEM:
Base classes/interfaces:
1. java.io.InputStream.read(byte[])
2. java.io.InputStream.read(byte[], int, int)
3. java.io.Reader.read(char[])
4. java.io.Reader.read(char[], int, int)
5. java.nio.ReadableByteChannel(ByteBuffer)
6. java.lang.Readable.read(CharBuffer)
Classes whose documentation isn't inherited from the base classes/
interfaces:
7. BufferedInputStream
8. BufferedReader
9. ByteArrayInputStream
10. DataInputStream
-- (not FileInputStream - says "no more data because ... end")
-- (not FilterInputStream - says "no more data because ... end")
11. InputStreamReader
12. LineNumberInputStream
(maybe not LineNumberReader - says " end ... _already_ ... reached"
13. ObjectInputStream
-- (not PipedInputStream - says "no more data because...")
-- (not PipedReader- says "no more data because...")
-- (not PushbackInputStream - says "no more data because...")
-- (not RandomAccessFile - says "no more data because...")
14. SequenceInputStream
-- (not StringBufferInputStream - says "no more data because...")
15. StringReader
16. ScatteringByteChannel
17. CharBuffer.read(CharBuffer)
18. CheckedInputStream
19. GZipInputStream
20. InflaterInputStream
21. ZipInputStream
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
See Description section.
ACTUAL -
See Description section.
URL OF FAULTY DOCUMENTATION :
http://java.sun.com/j2se/1.5.0/docs/api/java/nio/channels/ReadableByteChannel.html#read(java.nio.ByteBuffer)
(Incident Review ID: 296819)
======================================================================
- csr for
-
JDK-8284022 java.io bulk read(...) end-of-stream return value descriptions ambiguous
-
- Closed
-