I want to create an InputStream that is limited to a certain range of bytes in file, e.g. to bytes from position 0 to 100. So that the client code should see EOF once 100th byte is reached.
7 Answers
The read()
method of InputStream
reads a single byte at a time. You could write a subclass of InputStream
that maintains an internal counter; each time read()
is called, update the counter. If you have hit your maximum, do not allow any further reads (return -1 or something like that).
You will also need to ensure that the other methods for reading read_int
, etc are unsupported (ex: Override them and just throw UnsupportedOperationException());
I don't know what your use case is, but as a bonus you may want to implement buffering as well.

- 62,887
- 36
- 269
- 388

- 80,905
- 18
- 123
- 145
-
3I don't think there is any need to implement buffering - that's mixing concerns, and the way read(byte[]) works, returning up to the required amount of data, makes this unnecessary. It's cleaner and equally effective to wrap the base stream in a BufferedInputStream. – mdma May 22 '10 at 20:39
-
also NB that the only methods in InputStream that are declared abstract are read() and read(byte[], int, int) so sometimes you can get away with just defining those 2 (plus maybe close()) in your child class. – rogerdpack Feb 14 '13 at 18:03
As danben says, just decorate your stream and enforce the constraint:
public class ConstrainedInputStream extends InputStream {
private final InputStream decorated;
private long length;
public ConstrainedInputStream(InputStream decorated, long length) {
this.decorated = decorated;
this.length = length;
}
@Override public int read() throws IOException {
return (length-- <= 0) ? -1 : decorated.read();
}
// TODO: override other methods if you feel it's necessary
// optionally, extend FilterInputStream instead
}
-
1Code reuse (BoundedInputStream from commons-io): http://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/input/BoundedInputStream.html – CelinHC Apr 02 '14 at 18:14
Consider using http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/io/LimitInputStream.html

- 5,030
- 1
- 29
- 40
-
2LimitInputStream is scheduled to be removed in Guava release 15.0. Use ByteStreams.limit(java.io.InputStream, long) instead. – petertc Feb 07 '14 at 06:54
You can use guava's ByteStreams. Notice that you should use skipFully() before limit, for example:
ByteStreams.skipFully(tmpStream, range.start());
tmpStream = ByteStreams.limit(tmpStream, range.length());

- 3,607
- 1
- 31
- 36
If you only need 100 bytes, then simple is probably best, I'd read them into an array and wrap that as a ByteArrayInputStream. E.g.
int length = 100;
byte[] data = new byte[length];
InputStream in = ...; //your inputstream
DataInputStream din = new DataInputStream(din);
din.readFully(data);
ByteArrayInputStream first100Bytes = new ByteArrayInputStream(data);
// pass first100bytes to your clients
If you don't want to use DataInputStream.readFully
, there is IOUtils.readFully
from apache commons-io, or you can implment the read loop explicitly.
If you have more advanced needs, such as reading from a segment in the middle of the file, or larger amounts of data, then extending InputStream and overriding the read(byte[], int,int) as well as read(), will give you better performance than just overriding the read() method.

- 56,943
- 12
- 94
- 128
In addition to this solution, using the skip
method of an InputStream
, you can also read a range starting in the middle of the file.
public class RangeInputStream extends InputStream
{
private InputStream parent;
private long remaining;
public RangeInputStream(InputStream parent, long start, long end) throws IOException
{
if (end < start)
{
throw new IllegalArgumentException("end < start");
}
if (parent.skip(start) < start)
{
throw new IOException("Unable to skip leading bytes");
}
this.parent=parent;
remaining = end - start;
}
@Override
public int read() throws IOException
{
return --remaining >= 0 ? parent.read() : -1;
}
}
I was solved a similar problem for my project, you can see the working code here PartInputStream. I was used it for assets and files input streams. But it is not suitable for а streams whose length is not available initially, such as network streams.

- 1,759
- 15
- 15