From: Dennis on
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
From: markspace on
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).
From: EJP on
On 17/03/2010 11:59 PM, Dennis wrote:
>
> public class ForkedInputStream extends InputStream {

== java.io.SequenceInputStream, with more bugs
From: dennis on
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
From: dennis on
>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