Is there a way to divide an input stream into chunks? For instance, I am sending an input stream to a BodyPublisher, and I would like that BodyPublisher to read a subset of the input stream and stop, then, the next iteration would read the next set of bytes in the input stream.
I guess another way to ask this is, is there an input stream that can wrap another input stream and return end of stream after a specified number of bytes?
It might look something like:
InputStream is = // my inputstream
while (bytesRead < numBytes) {
SubsetInputStream subsetIs = new SubsetInputStream(is, chunkSize);
...
.POST(HttpRequest.BodyPublishers.ofInputStream(() -> subsetIs));
...
bytesRead += chunkSize;
}
Seems trivial to make it yourself:
import java.io.*;
public class LimitedInputStream extends FilterInputStream {
private int limit;
public LimitedInputStream(InputStream in, int limit) {
super(in);
if (in == null) throw new NullPointerException("in");
if (limit < 1) throw new IllegalArgumentException("limit must be positive");
this.limit = limit;
}
@Override public int read() throws IOException {
if (limit < 1) return -1;
limit--;
return in.read();
}
@Override public int read(byte[] b, int off, int len) throws IOException {
if (limit < 1) return -1;
int lim = Math.min(len, limit);
int r = in.read(b, off, lim);
if (r > 0) limit -= r;
return r;
}
@Override public void close() throws IOException {
in.close();
}
@Override public long skip(long n) throws IOException {
long lim = Math.min(n, limit);
long r = in.skip(lim);
if (r > 0) limit -= r;
return r;
}
@Override public int available() throws IOException {
return Math.min(in.available(), limit);
}
public static void main(String[] args) throws Exception {
var raw = new ByteArrayInputStream(new byte[256]);
var lim = new LimitedInputStream(raw, 100);
byte[] b = new byte[55];
System.out.println(lim.read(b)); // prints 55
lim.read();
lim.read();
System.out.println(lim.read(b)); // prints 43
System.out.println(lim.read(b)); // prints -1
}
}