wood burning stoves 2.0*
The moose likes I/O and Streams and the fly likes About BufferedInputStream set method Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Soft Skills this week in the Jobs Discussion forum!
JavaRanch » Java Forums » Java » I/O and Streams
Bookmark "About BufferedInputStream set method" Watch "About BufferedInputStream set method" New topic
Author

About BufferedInputStream set method

Hk Cheung
Greenhorn

Joined: Apr 21, 2011
Posts: 11
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

Joined: Oct 27, 2005
Posts: 19783
    
  20

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.


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
Hk Cheung
Greenhorn

Joined: Apr 21, 2011
Posts: 11
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

Joined: Oct 27, 2005
Posts: 19783
    
  20

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.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: About BufferedInputStream set method