Seeking a ByteArrayInputStream using java.io

2019-02-12 14:52发布

How can I seek (change the position) of a ByteArrayInputStream (java.io)? It is something so obvious, but I can't seem to find a method for this anywhere (mark/reset is not enough, I need to set the position to anywhere on the InputStream).

If it can't be done using java.io and I must switch to java.nio and use a ByteBuffer, how can I get something similar to a DataOutputStream wrapping a ByteArrayOutputStream using java.nio? I'm not finding any kind of auto-resizable buffer.

EDIT: I've found one way to achieve what I'm attempting to do, but it's a bit messy. ImageIO.createImageInputStream creates a ImageInputStream, which is exactly what I want (can seek and read primitives). However, using a ByteArrayInputStream returns a FileCacheImageInputStream, which basically means it copies the byte array to a file just to seek.

This is my first time trying to use the Java IO classes and it has been completely negative. It's missing some fundamental (IMO) features, and it has lots of ways to do the same thing (e.g. to read primitives from a file you can either use RandomAccessFile, DataInputStream + FileInputStream, FileImageInputStream, FileChannel + ByteBuffer, and maybe even more).

标签: java io stream nio
3条回答
甜甜的少女心
2楼-- · 2019-02-12 15:33

There is a ByteArrayInputStream(byte(), int, int) constructor that will give you an input stream that will read up to a given count of bytes starting from a given offset. You can use this to simulate seeking to an arbitrary offset in the stream.

You have to deal with the fact that "seeking" gives you a new stream object, and this may be awkward. However, this approach does not involve copying any bytes or saving them to a file, and it should be safe to not bother with closing the ByteArrayInputStream objects.

查看更多
看我几分像从前
3楼-- · 2019-02-12 15:40

You'd use reset()/skip(). I can't say it's the nicest API in the world, but it should work:

public void seek(ByteArrayInputStream input, int position)
    throws IOException
{
    input.reset();
    input.skip(position);
}

Of course, that assumes that no-one has called mark().

查看更多
▲ chillily
4楼-- · 2019-02-12 15:45

If you are creating the ByteArrayInputStream to pass elsewhere, extend the class and manipulate pos (a protected member of ByteArrayInputStream) as you wish.

查看更多
登录 后发表回答