Say you want to perform some sort of operation on the data in an InputStream, e.g. the audio data in a WAV file. You cycle through it char by char until you reach the end of the stream, writing to an OutputStream as you go. Now you want to perform a second operation on the modified stream you've just created. Is there a way to then open a new InputStream which reads what you've just written to the OutputStream (without first writing to a file)?
Ummm... I hope you're not really treating bytes from an audio stream as "chars"; that's going to be pretty confusing. As to your question - you could achieve this using a PipedOutputStream and PipedInputStream I think. You write to the PipedOutputStream, and create another thread that reads from the attached PipedInputStream and does whatever you want with the data. However it may well be more efficient to implement whatever additional processing you want using a single class that extends FilterOutputStream. Then just chain the FilterInputStream on to whatever other OutputStream you want to write to.
Jim, do you know any examples like this? I wanted to make a bunch of filter objects that I could plug together in different combinations kinda like using Unix pipes. I played with it for about ten minutes and decided I wasn't quite ready. Is that what the piped classes are for?
A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
Joined: Jan 30, 2000
I think so. I don't know a good complete example of this off the top of my head, and I've never actually had a problem where I needed the piped streams - I always managed to refactor things so I was looking at one of the streams from the other end, and suddenly things seemed simpler. But if you have a component A which accepts an OutputStream as a parameter, and a component B which accepts an InputStream as a parameter, and A needs to do something before B and those steams are the expected ways to get data in/out of the specified components, and you can't edit either A or B to give you a more intuitive interface ,, then piped streams are probably what you need:
A key point is that the components need to be in separate threads, since whoever has the InputStream will block until the OutputStream is written to. It all seems rather backwards to me most of the time, so if I can find a way to refactor A or B, I usually do so. A good example of component B might be a SAXParser, which takes an InputStream as a parameter to its parse() method. At the moment I'm blanking on a good example for A that would go with this, but there's probably something out there. Alternately, if A does something before B, and A takes an InputStream while B takes an OutputStream, it's much simpler:
That's the paradigm I'm more used to operating in, but sometimes that's not what we have to work with.