Win a copy of Functional Reactive Programming this week in the Other Languages forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

About BufferedInputStream set method

 
Hk Cheung
Greenhorn
Posts: 12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi everyone,

I have a BufferedInputStream in my program and I want to use the whole stream multiple times, so I wrote my code like this:

BufferedInputStream bis = new BufferedInputStream(inputStream);
if (bis.markSupported()) {
bis.mark(bis.available());
}

However when I called bis.mark() afterwards, there was a java.io.IOException: Resetting to invalid mark which indicate that the mark had became invalid.

May I know why the Exception happened since I've already assigned the whole size of the stream to the readlimit parameter of the mark method?

Thanks!

Kit
 
Rob Spoor
Sheriff
Pie
Posts: 20667
65
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch!

You didn't mark the entire stream, just what was available at the time. There are absolutely no guarantees about what available() will return. See also Available Doesn't Do What You Think It Does.

Perhaps you should copy the contents of the input stream to a ByteArrayOutputStream, then use a ByteArrayInputStream. Because you will have copied the entire contents you know the size of the contents. This isn't even necessary however, as a ByteArrayInputStream by default puts a mark at the start / offset, and resetting will go back to this mark no matter how much data you requested to be read.
 
Hk Cheung
Greenhorn
Posts: 12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rob Spoor wrote:Welcome to the Ranch!

You didn't mark the entire stream, just what was available at the time. There are absolutely no guarantees about what available() will return. See also Available Doesn't Do What You Think It Does.

Perhaps you should copy the contents of the input stream to a ByteArrayOutputStream, then use a ByteArrayInputStream. Because you will have copied the entire contents you know the size of the contents. This isn't even necessary however, as a ByteArrayInputStream by default puts a mark at the start / offset, and resetting will go back to this mark no matter how much data you requested to be read.


Hi Rob, thanks for your reply

Actually I also wrote another program which is exactly like your suggested approach(lets say approach 2). Since I have to use the whole BufferedInputStream for three times, for approach 2 that means I have to create three ByteArrayInputStream objects as output which requires more memory, whereas the original approach only reads data from a single stream object.

If my original approach really not feasiable, I will just proceed with the suggested approach.

P.S. I find this forum(or ranch) very useful and I will come here more often!
 
Rob Spoor
Sheriff
Pie
Posts: 20667
65
Chrome Eclipse IDE Java Windows
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You don't need three ByteArrayInputStream objects. Just use its reset() method without calling mark, that will reset it to the starting position.

And even if you create three ByteArrayInputStream objects, just use the same byte[]. The three instances will then share the same data, and the only extra memory is needed for three int instance fields of ByteArrayInputStream, one reference field (to the byte[]) and the object overhead. That's not a lot.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic