in priam/src/main/java/com/netflix/priam/backup/RangeReadInputStream.java [50:87]
public int read(final byte b[], final int off, final int len) throws IOException {
if (fileSize > 0 && offset >= fileSize) return -1;
final long firstByte = offset;
long curEndByte = firstByte + len;
curEndByte = curEndByte <= fileSize ? curEndByte : fileSize;
// need to subtract one as the call to getRange is inclusive
// meaning if you want to download the first 10 bytes of a file, request bytes 0..9
final long endByte = curEndByte - 1;
try {
return new RetryableCallable<Integer>() {
public Integer retriableCall() throws IOException {
GetObjectRequest req = new GetObjectRequest(bucketName, remotePath);
req.setRange(firstByte, endByte);
try (S3ObjectInputStream is = s3Client.getObject(req).getObjectContent()) {
byte[] readBuf = new byte[4092];
int rCnt;
int readTotal = 0;
int incomingOffet = off;
while ((rCnt = is.read(readBuf, 0, readBuf.length)) >= 0) {
System.arraycopy(readBuf, 0, b, incomingOffet, rCnt);
readTotal += rCnt;
incomingOffet += rCnt;
}
if (readTotal == 0 && rCnt == -1) return -1;
offset += readTotal;
return readTotal;
}
}
}.call();
} catch (Exception e) {
String msg =
String.format(
"failed to read offset range %d-%d of file %s whose size is %d",
firstByte, endByte, remotePath, fileSize);
throw new IOException(msg, e);
}
}