开发者

Copy the start of an InputStream

I want to copy the "start" (i.e., first N characters) of an InputStream and then reset the stream to its start, so that it can be reused.

Using mark() and reset() does not work for all types of input streams, so I was wondering if there is a "generic" open source Java class (i.e., a stream wrapper) that can do th开发者_开发知识库is for any type of input stream.

Also, what would be the safest way of making the copy to avoid conversion errors?


Maybe you could wrap your InputStream in a PushbackInputStream so you could read the first N bytes then unread() them for reuse of the stream.


Take a look at how apache commons IOUtils copies stream IOUtils#copyLarge().

You can use populate ab ByteArrayInputStream such a way.

  • byte[] buffer = new byte[n]; // n is the size from start
  • pupulate the buffer using technique from IOUtils#copyLarge()
  • create your ByteArrayInputStream using the buffer you created earlier

Here is the code snippet to IOUtils#copyLarge()

public static long copyLarge(InputStream input, OutputStream output)
        throws IOException {
    byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
    long count = 0;
    int n = 0;
    while (-1 != (n = input.read(buffer))) {
        output.write(buffer, 0, n);
        count += n;
    }
    return count;
}


When it comes to reusing a stream and size doesn't matter (e.g. a few mega bytes), getting the byte[] of the stream once, and then recreating ByteArrayInputStream objects with the stored byte[] when necessary has always worked for me. No more trouble with mark() and reset().


After quite a bit of experimentation, it seems that the best (although imperfect) approach is to use the mark() and reset() methods of the InputStream.

If the original stream does not support marking/resetting, an easy workaround is to wrap it inside a BufferedInputStream.*

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜