HDFS-10277. PositionedReadable test testReadFullyZeroByteFile failing in HDFS. Contributed by Steve Loughran.
(cherry picked from commita409508b3f
) (cherry picked from commit8f968171bd
)
This commit is contained in:
parent
9d4dedd65f
commit
e2b8bdbe0a
|
@ -120,7 +120,8 @@ Return the data at the current position.
|
||||||
### <a name="InputStream.read.buffer[]"></a> `InputStream.read(buffer[], offset, length)`
|
### <a name="InputStream.read.buffer[]"></a> `InputStream.read(buffer[], offset, length)`
|
||||||
|
|
||||||
Read `length` bytes of data into the destination buffer, starting at offset
|
Read `length` bytes of data into the destination buffer, starting at offset
|
||||||
`offset`
|
`offset`. The source of the data is the current position of the stream,
|
||||||
|
as implicitly set in `pos`
|
||||||
|
|
||||||
#### Preconditions
|
#### Preconditions
|
||||||
|
|
||||||
|
@ -129,6 +130,7 @@ Read `length` bytes of data into the destination buffer, starting at offset
|
||||||
length >= 0
|
length >= 0
|
||||||
offset < len(buffer)
|
offset < len(buffer)
|
||||||
length <= len(buffer) - offset
|
length <= len(buffer) - offset
|
||||||
|
pos >= 0 else raise EOFException, IOException
|
||||||
|
|
||||||
Exceptions that may be raised on precondition failure are
|
Exceptions that may be raised on precondition failure are
|
||||||
|
|
||||||
|
@ -136,20 +138,39 @@ Exceptions that may be raised on precondition failure are
|
||||||
ArrayIndexOutOfBoundsException
|
ArrayIndexOutOfBoundsException
|
||||||
RuntimeException
|
RuntimeException
|
||||||
|
|
||||||
|
Not all filesystems check the `isOpen` state.
|
||||||
|
|
||||||
#### Postconditions
|
#### Postconditions
|
||||||
|
|
||||||
if length == 0 :
|
if length == 0 :
|
||||||
result = 0
|
result = 0
|
||||||
|
|
||||||
elseif pos > len(data):
|
else if pos > len(data):
|
||||||
result -1
|
result = -1
|
||||||
|
|
||||||
else
|
else
|
||||||
let l = min(length, len(data)-length) :
|
let l = min(length, len(data)-length) :
|
||||||
buffer' = buffer where forall i in [0..l-1]:
|
buffer' = buffer where forall i in [0..l-1]:
|
||||||
buffer'[o+i] = data[pos+i]
|
buffer'[o+i] = data[pos+i]
|
||||||
FSDIS' = (pos+l, data, true)
|
FSDIS' = (pos+l, data, true)
|
||||||
result = l
|
result = l
|
||||||
|
|
||||||
|
The `java.io` API states that if the amount of data to be read (i.e. `length`)
|
||||||
|
then the call must block until the amount of data available is greater than
|
||||||
|
zero —that is, until there is some data. The call is not required to return
|
||||||
|
when the buffer is full, or indeed block until there is no data left in
|
||||||
|
the stream.
|
||||||
|
|
||||||
|
That is, rather than `l` being simply defined as `min(length, len(data)-length)`,
|
||||||
|
it strictly is an integer in the range `1..min(length, len(data)-length)`.
|
||||||
|
While the caller may expect for as much as the buffer as possible to be filled
|
||||||
|
in, it is within the specification for an implementation to always return
|
||||||
|
a smaller number, perhaps only ever 1 byte.
|
||||||
|
|
||||||
|
What is critical is that unless the destination buffer size is 0, the call
|
||||||
|
must block until at least one byte is returned. Thus, for any data source
|
||||||
|
of length greater than zero, repeated invocations of this `read()` operation
|
||||||
|
will eventually read all the data.
|
||||||
|
|
||||||
### <a name="Seekable.seek"></a>`Seekable.seek(s)`
|
### <a name="Seekable.seek"></a>`Seekable.seek(s)`
|
||||||
|
|
||||||
|
|
|
@ -973,6 +973,10 @@ public class DFSInputStream extends FSInputStream
|
||||||
@Override
|
@Override
|
||||||
public synchronized int read(@Nonnull final byte buf[], int off, int len)
|
public synchronized int read(@Nonnull final byte buf[], int off, int len)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
validatePositionedReadArgs(pos, buf, off, len);
|
||||||
|
if (len == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
ReaderStrategy byteArrayReader = new ByteArrayStrategy(buf);
|
ReaderStrategy byteArrayReader = new ByteArrayStrategy(buf);
|
||||||
try (TraceScope ignored =
|
try (TraceScope ignored =
|
||||||
dfsClient.newPathTraceScope("DFSInputStream#byteArrayRead", src)) {
|
dfsClient.newPathTraceScope("DFSInputStream#byteArrayRead", src)) {
|
||||||
|
|
Loading…
Reference in New Issue