PipedInputStream Wrap Using BufferedInputStream

I have an OutputStream with which I needed to read, and therefore I used the following (Groovy) code to get the InputStream link for the data:

PipedInputStream inputStream = new PipedInputStream() PipedOutputStream outputStream = new PipedOutputStream(inputStream) new Thread( new Runnable() { public void run() { // Some API method putDataInOutputStream(outputStream) outputStream.close() } } ).start() handler.process(inputStream) 

In this case, the handler is some class that implements the interface that this method has:

 public void process(InputStream stream); 

The problem that arose in our new requirements was that there was some preprocessing in the stream, so I need to read the stream at least twice in the handler.process () method. Here is a sample code from one implementation:

 public void process(InputStream stream) { def bufferedStream = new BufferedInputStream(stream, 30 * 1048576) // 30 MB bufferedStream.mark(Integer.MAX_VALUE) parseMetadata(bufferedStream) bufferedStream.reset() doTheThingYouDo(bufferedStream) } 

I know that for some input I am not pushing the limit of 30 MB or the size of Integer.MAX_VALUE . However, I always get the following exception:

 java.io.IOException: Stream closed 

Is it possible? I think the problem is closing the stream in PipedOutputStream, but I donโ€™t know how to prevent this, or maybe I am creating more problems, being new to Java Stream IO.

+4
source share
1 answer

My best guess is that your parseMetadata somehow closed the stream. I tried my script and it works great for me. As a rule, closing the OutputStream before the handler completes is not a problem, this is what streams with channels are for.

In addition, given your situation, I would give up the pipeline and the extra thread. If you don't mind that your entire thread is in memory, you can do something like

 ByteArrayOutputStream out = new ByteArrayOutputStream(); fillTheOutput(out); ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); pass1(in); in.reset(); pass2(in); 

If you have everything in memory, you have everything in order, as your BufferedInputStream does about the same.

to change . Please note: you can easily create a new ByteArrayInputStream based on an array of bytes, which you cannot do with regular streams.

+2
source

Source: https://habr.com/ru/post/1339092/


All Articles