DataInputStream.readFully fills the requested region or throws EOFException, and an EOF failure may occur after some destination bytes were changed.
Java DataInputStream.readFully: EOF can leave partial bytes in the buffer
Keep tentative data private
A caller should not reuse a partially filled buffer as though it were a complete record. Allocate the record buffer inside the operation, invoke readFully, then return it only on success. The exception is part of the framing contract; it is not permission to process the bytes already copied.
The first read succeeds. The second throws after two bytes, and the program prints the private buffer so the partial mutation is visible. readNBytes expresses a similar boundary through a short returned array instead.
Bound the destination before reading
readFully does not decide whether a declared record size is safe. Validate the protocol length before allocating. For a long-running stream, also consider cancellation and deadlines; a blocking read can wait for remaining bytes.
Working program
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.util.Arrays;
public class InvoiceRecordBoundary {
static byte[] record(byte[] wire) throws IOException {
byte[] destination = new byte[4];
try (DataInputStream input = new DataInputStream(new ByteArrayInputStream(wire))) {
input.readFully(destination);
}
return destination;
}
public static void main(String[] args) throws IOException {
System.out.println(Arrays.toString(record(new byte[] {7, 8, 9, 10})));
byte[] tentative = new byte[4];
try (DataInputStream input = new DataInputStream(new ByteArrayInputStream(new byte[] {7, 8}))) {
try { input.readFully(tentative); }
catch (EOFException truncated) { System.out.println(Arrays.toString(tentative)); }
}
}
}Output
[7, 8, 9, 10]
[7, 8, 0, 0]Cost and ownership
The fixed four-byte buffer costs O(1) space here; a general record of length n costs O(n) storage and read work. A failed read retains only tentative local data, so callers cannot accidentally publish an incomplete record.
Common Mistakes
- Do not assume an exception leaves the destination unchanged.
- Do not expose a record buffer before readFully returns.
- Do not allocate an unbounded buffer from an external length.
Read next
Java InputStream short reads: assemble a complete record header, Java readNBytes: reject a truncated payload after the header, Java byte streams: partial reads and bounded copying, Java try-with-resources: close order and suppressed failures.
