Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Java (http://www.velocityreviews.com/forums/f30-java.html)
-   -   Forking Inputstream: Am I missing something (http://www.velocityreviews.com/forums/t717982-forking-inputstream-am-i-missing-something.html)

Dennis 03-17-2010 12:59 PM

Forking Inputstream: Am I missing something
 
Dear all,

This has been puzzling me all morning: There is reasonable elegant way (see example below) to log InputStreams and OutputStreams, without consuming the streams. However, I cannot find any reference to it or a good implementation of it anywhere. I tested it and it seems to work, but I have the nagging idea that I'm missing something, or I did miss all the references to it on the internet.

public class ForkedInputStream extends InputStream {

private InputStream m_source;
private OutputStream m_fork;

public ForkedInputStream(InputStream source, OutputStream fork) {
m_source = source;
m_fork = fork;
}

public int read() throws IOException {
int b = m_source.read();
if (b==-1) {
m_fork.flush();
} else {
m_fork.write(b);
}

return b;
}

public int available() throws IOException {
return m_source.available();
}

public void close() throws IOException {
m_fork.close();
}
}

You can feed in your original InputStream to ForkedInputStream and use the instance of ForkedInputStream as you would the original stream. The OutputStream will now contain the same information as read from the InputStream.

Off course you could enhance it with Threading, Buffers and a check to only write at certain (log) levels
This would take care of the only two issues I can think of, but the principle stays the same:
- A blocked output would block the read() operation.
- Writing to the OutputStream takes time, so you might not have it 'on' in every situation.
Or as the title suggests: Am I missing something?

Kind regards,
Dennis
Brains2B.org

markspace 03-17-2010 04:18 PM

Re: Forking Inputstream: Am I missing something
 
Dennis wrote:

> public void close() throws IOException {
> m_fork.close();


You probably should close the input stream here too.

> }



Aside from that the only comment I have is that this will be very
inefficient, since you don't override read( byte[], int, int ) and
therefore can't read more than one byte (via the method you do override,
read()) at a time.

Next step: override read(byte[]) and read(byte[],int,int).

EJP 03-18-2010 09:49 AM

Re: Forking Inputstream: Am I missing something
 
On 17/03/2010 11:59 PM, Dennis wrote:
>
> public class ForkedInputStream extends InputStream {


== java.io.SequenceInputStream, with more bugs

dennis 03-18-2010 07:37 PM

Re: Forking Inputstream: Am I missing something
 
Hi markspace,

>Aside from that the only comment I have is that this will be very
>inefficient, since you don't override read( byte[], int, int ) and
>therefore can't read more than one byte (via the method you do override,
>read()) at a time.
>Next step: override read(byte[]) and read(byte[],int,int).


Thanks for your comments. I left the other read implementations out in the example for clarity but you are right they should be there. The close was just me being to hasty.

Kind regards,
Dennis

dennis 03-18-2010 07:42 PM

Re: Forking Inputstream: Am I missing something
 
>On 17/03/2010 11:59 PM, Dennis wrote:
>>
>> public class ForkedInputStream extends InputStream {

>== java.io.SequenceInputStream, with more bugs


Hi,

Thanks for the pointer to SequenceInputStream. However SequenceInputStream just takes InputStream and there is no SequenceOutputStream. Which gets met back to the original question: what am I missing if 'forking' OutputStreams is not done.

What bugs did you find?

Kind regards,
Dennis

Ian Shef 03-19-2010 12:40 AM

Re: Forking Inputstream: Am I missing something
 
EJP <esmond.not.pitt@not.bigpond.com> wrote in news:TGmon.13637$pv.10376
@news-server.bigpond.net.au:

> On 17/03/2010 11:59 PM, Dennis wrote:
>>
>> public class ForkedInputStream extends InputStream {

>
> == java.io.SequenceInputStream, with more bugs


I don't think so.
You might be correct about the bugs, but not about the equivalence.

From the Javadocs:
"A SequenceInputStream represents the logical concatenation of other input
streams."

A SequenceInputStream performs concatenation. A ForkedInputStream provides
what I would call a Tee. It provides input, and also echoes that input to
the designated OutputStream.

--------

The original poster might want to look at
http://commons.apache.org/io/apidocs...t/TeeInputStre
am.html

for another implementation of this idea. It has more features and possibly
fewer bugs.

The sources are open, for some definition of "open".

See
http://svn.apache.org/viewvc/commons...rg/apache/comm
ons/io/input/TeeInputStream.java?view=markup






Mike Schilling 03-19-2010 12:42 AM

Re: Forking Inputstream: Am I missing something
 
Dennis wrote:
> Dear all,
>
> This has been puzzling me all morning: There is reasonable elegant
> way (see example below) to log InputStreams and OutputStreams,
> without consuming the streams. However, I cannot find any reference
> to it or a good implementation of it anywhere. I tested it and it
> seems to work, but I have the nagging idea that I'm missing
> something, or I did miss all the references to it on the internet.


I'd probably extend FilterInputStream and just call super() for all the
processing of the "main" stream e,g,

public class TeeInputStream extends FilterInputStream
{
private OutputStream m_tee;

public TeeInputStream(InputStream in, OutputStream fork)
{
super(in);
}

public int read() throws IOException
{
int c = super.read();
if (b == -1)
m_tee.flush();
else
m_tee.write(c);
}

public void close() throws IOException
{
super.close();
m_tee.close();
}

// etc.
}



EJP 03-19-2010 01:17 AM

Re: Forking Inputstream: Am I missing something
 
On 18/03/2010 8:49 PM, EJP wrote:
> == java.io.SequenceInputStream, with more bugs


Sorry, I am crazy, it is actually more like tee(1). I wrote a
TeeInputStream at some point about 10 years ago, wonder where it is.

dennis 03-20-2010 05:44 PM

Re: Forking Inputstream: Am I missing something
 
>The original poster might want to look at
>http://commons.apache.org/io/apidocs...t/TeeInputStre
>am.html
>for another implementation of this idea. It has more features and possibly
>fewer bugs.


Hi Ian,

Thanks for the reference. This was helpfull. At least now I know it has been done before (and with no unexpected side effects).
I'm not sure yet if I want to use that one directly, or use my own implementation:
- One they are using ProxyInputStream which possibly allows for seek(),mark() and reset() of the underlying stream and this could mean part of the output would not be written multiple times or not at all. You either have to handle that or at least mark the output that there was a part not written or written multiple times. Especially when you use it for logging or storing xml-requests
- The license issue. If I use mine it will be done under the modified BSD-license so no restrictions to future users.

Kind regards,
Dennis




dennis 03-20-2010 05:49 PM

Re: Forking Inputstream: Am I missing something
 
Hi Mike,

Thanks for the feedback. I looked into FilterInputStream, but did not want to use it while the underlying stream might support seek(), mark() and reset() and this will prevent data being written to the output or data being written multiple times. You either have to handle that or at least mark the output that there was a part not written or writtenmore then once. Especially when you use it for logging or storing xml-requests.

Kind regards,
Dennis..


All times are GMT. The time now is 05:14 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.