0

Is there any simple and efficient way to duplicate an InputStreamReader?

6
  • 4
    What kind of behavior do you want to support by duplicating? Commented Jul 15, 2010 at 7:32
  • so that the reader can be read by two objects at the moment... Commented Jul 15, 2010 at 7:37
  • @howa.wong: so one InputStreamReader object being consumed by multiple threads with proper synchronized access? That's not really duplicating but rather just sharing of mutable data in a concurrent scenario. Is this what you want? Commented Jul 15, 2010 at 7:56
  • @polygenelubricants yes, I need a reader which can be read by two threads independently Commented Jul 15, 2010 at 7:59
  • @howa.wong: still not clear what "independently" means. If the underlying input stream has ABC, should both threads be able to read ABC whenever they start reading, or if thread1 reads A then thread2 misses out on it and can only read BC? Commented Jul 15, 2010 at 8:41

2 Answers 2

1

According to the comments, wouldn't it then be better to create 1 object that reads the data and sends it to registered readers?

class Reader {
   void registerReceiver(Receiver r) {
     // add reciever
   };
   void unRegisterReceiver(Receiver r) {
     // remove reciever
   };
   // do reading from inputstream in implementation 
   // and send read data to receivers
}
interface Reciever {
   void receive(byte [] data);
}
Sign up to request clarification or add additional context in comments.

Comments

0

The answer is that there is no general solution to this problem that is both simple and efficient ... and that always works. The root problem is that an arbitrary InputStream or Reader may deliver an indefinitely large amount of data. Certainly more data than you would want to buffer in memory. (Lots of data ==> OutOfMemoryError.)

If you want a really simple solution, then just read the entire InputStream using an InputStreamReader and write its contents to a CharArrayWriter. Then open two (or more) CharArrayReaders ... and you've effectively duplicated the InputStream. There are two obvious problems:

  • The entire stream is buffered in memory.
  • The entire stream has to be read and buffered before you can hand out the Readers to consumers of the data.

To avoid using too much memory a "duplicating" InputStream / Reader needs to be able to write unread data into a temporary file, and then read back from the same file. This gets rather complicated, rather quickly. Even without the temporary file, it is still a bit tricky to implement a version that doesn't have to read the entire stream first, and that doesn't have the problem that not reading one of the Readers blocks the other one.

I suppose that you could implement this by creating two PipeInputStream / PipeOutputStream pairs with a pipeSize argument that is as large as the amount that the two Readers are likely to get out of step. But in the worst case, you need buffers big enough to hold twice the size of the stream contents ... and this approach will result in a lot of extra data copying. In other words, this approach hardly counts as efficient.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.