0

I'm working on a task and have had a question on the code review- 'do we need to ensure the input stream is consumed here?'

public void processInputStream(final DataInputStream dataInputStream, final OutputStream output) {
        try {
            // doing something with dataInputStream!!
        } catch (IOException e) {
            // doing something with IOException
        }
}

I have a few questions -

#1 I assume that if the InputStream processing is interrupted, then my catch block will be triggered. Is that correct? And if so, does that negate the need to ensure that the stream has been consumed?

#2 How would I check the InputStream has been consumed in this case?

Thanks

Update -

Part of processing my InputStream involves using -

copyInputStreamToFile(..)

From Apache commons https://commons.apache.org/proper/commons-io/javadocs/api-2.7/org/apache/commons/io/FileUtils.html#copyInputStreamToFile-java.io.InputStream-java.io.File-

Their documentation says -

Copies bytes from an InputStream source to a file destination. The directories up to destination will be created if they don't already exist. destination will be overwritten if it already exists. The source stream is closed. See copyToFile(InputStream, File) for a method that does not close the input stream.

Does this mean that given the source stream is closed, then this covers checking the InputStream has been consumed?

Johnny Alpha
  • 758
  • 1
  • 8
  • 35
  • 3
    You don't need to ensure that it is consumed, but probably that the `close()` method is called. Best would be if you use the [try-with-resources-statement](https://stackoverflow.com/questions/17739362/whats-the-purpose-of-try-with-resources-statements) – Lino Feb 01 '21 at 12:12
  • 1
    There is `available()` method that returns number of bytes that can be read from stream (depending on the specific implementation). Probably you can check its result – Nikolai Shevchenko Feb 01 '21 at 12:19
  • 1
    @NikolaiShevchenko the `available` method returns the number of bytes that are *immediately* available (the method may return `0` even if the stream is not fully consumed) – Felix Feb 01 '21 at 12:21
  • 1
    Yes, the `copyInputStreamToFile` will make sure the whole stream is copied. – daniu Feb 01 '21 at 12:29
  • 1
    `copyInputStreamToFile` consumes the whole InputStream and writes it to the specified file, but you should still close the InputStream yourself (for example by using try-with-resources) – Felix Feb 01 '21 at 12:40

3 Answers3

0

You could check whether an InputStream is exhausted or not using this method:

package example;

import java.io.IOException;
import java.io.InputStream;

public class SO {

    public static boolean isExhausted(InputStream in) throws IOException {
        final boolean exhausted;

        if (in.markSupported()) {
            in.mark(1);
            exhausted = in.read() == -1;
            in.reset();
        } else {
            throw new IllegalStateException("mark is not supported on this inputstream");
        }

        return exhausted;
    }
}

Note that this only works if the InputStream supports mark and reset methods (in.markSupported())

Felix
  • 2,256
  • 2
  • 15
  • 35
0

This did the trick!

private void consumeQuietly(final InputStream inputStream) {
    try (OutputStream out = NullOutputStream.NULL_OUTPUT_STREAM) {
        IOUtils.copy(inputStream, out);
    } catch (IOException ioException) {
        // Log something!!
    }
}
Johnny Alpha
  • 758
  • 1
  • 8
  • 35
  • Even if this somehow results in what you want, it seems a hacky way to me. Could you describe what you really wanted to achieve so that we can give you some advice? – Felix Feb 01 '21 at 14:14
-2
public void processInputStream(final DataInputStream dataInputStream, final OutputStream output)
{
    try
    {
        // doing something with dataInputStream!!
    }
    catch (InterruptedException ie)
    {
        // doing something with InterruptedException

    }
    catch (IOException ioe)
    {
        // doing something with IOException
    }
}

You can utilize inputStream.available() method to determine whether input stream is consumed or not.

Harsh_Jani
  • 27
  • 1
  • 2
    the `available()` method returns the number of bytes that are *immediately* available (the method may return `0` even if the stream is not fully consumed) – Felix Feb 01 '21 at 12:38
  • 1
    Then you need to create a customized class which extends InputStream and provide some behavior into it. Or you can utilize java.io.PushbackInputStream which allows you to read from the stream to see if there's something there, and then "push it back" up the stream (that's not how it really works, but that's the way it behaves to client code). Thanks – Harsh_Jani Feb 01 '21 at 13:45
  • 1
    FYI, In first question you can utilize the catch block with InterruptedException related code. – Harsh_Jani Feb 01 '21 at 13:47