我想创建一个仅限于文件中某个字节范围的InputStream,例如从位置0到100的字节。因此客户端代码应在达到第100个字节时看到EOF。
答案 0 :(得分:10)
read()
InputStream
方法一次读取一个字节。你可以编写一个InputStream
的子类来维护一个内部计数器;每次调用read()
时,都要更新计数器。如果达到最大值,则不允许进一步读取(返回-1或类似的东西)。
您还需要确保不支持读取read_int
等其他方法(例如:覆盖它们并抛出UnsupportedOperationException());
我不知道你的用例是什么,但作为奖励,你可能也希望实现缓冲。
答案 1 :(得分:8)
作为danben says,只需装饰你的流并强制执行约束:
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
}
答案 2 :(得分:4)
考虑使用http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/io/LimitInputStream.html
答案 3 :(得分:2)
如果你只需要100个字节,那么simple可能是最好的,我将它们读入一个数组并将其包装为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
如果您不想使用DataInputStream.readFully
,那么apache commons-io中会有IOUtils.readFully
,或者您可以明确地使用读取循环。
如果您有更高级的需求,例如从文件中间的段读取,或者更大量的数据,那么扩展InputStream并覆盖read(byte [],int,int)以及read( ),将提供比仅覆盖read()方法更好的性能。
答案 4 :(得分:2)
你可以使用番石榴的ByteStreams。 请注意,您应该在limit之前使用skipFully(),例如:
ByteStreams.skipFully(tmpStream, range.start());
tmpStream = ByteStreams.limit(tmpStream, range.length());
答案 5 :(得分:2)
除了this解决方案,使用skip
的{{1}}方法,您还可以读取从文件中间开始的范围。
InputStream
答案 6 :(得分:0)
我的项目遇到了类似的问题,你可以在这里查看工作代码PartInputStream。 我用它来资产和文件输入流。但它不适合最初不可用的流,例如网络流。