With Java 11, I could initialize an InputStream
as:
InputStream inputStream = InputStream.nullInputStream();
But I am unable to understand a potential use case of InputStream.nullInputStream
or a similar API for OutputStream
i.e. OutputStream.nullOutputStream
.
From the API Javadocs, I could figure out that it
Returns a new
InputStream
that reads no bytes. The returned stream is initially open. The stream is closed by calling the close() method.Subsequent calls to
close()
have no effect. While the stream is open, theavailable()
,read()
,read(byte[])
, ...skip(long)
, andtransferTo()
methods all behave as if end of stream has been reached.
I went through the detailed release notes further which states:
There are various times where I would like to use methods that require as a parameter a target OutputStream/Writer for sending output, but would like to execute those methods silently for their other effects.
This corresponds to the ability in Unix to redirect command output to /dev/null, or in DOS to append command output to NUL.
Yet I fail to understand what are those methods in the statement as stated as .... execute those methods silently for their other effects. (blame my lack of hands-on with the APIs)
Can someone help me understand what is the usefulness of having such an input or output stream with a help of an example if possible?
Edit: One of a similar implementation I could find on browsing further is apache-commons' NullInputStream
, which does justify the testing use case much better.
Class OutputStream. This abstract class is the superclass of all classes representing an output stream of bytes. An output stream accepts output bytes and sends them to some sink. Applications that need to define a subclass of OutputStream must always provide at least a method that writes one byte of output.
InputStream , represents an ordered stream of bytes. In other words, you can read data from a Java InputStream as an ordered sequence of bytes. This is useful when reading data from a file, or received over the network.
InputStream class is the superclass of all the io classes i.e. representing an input stream of bytes. It represents input stream of bytes. Applications that are defining subclass of InputStream must provide method, returning the next byte of input.
Sometimes you want to have a parameter of InputStream type, but also to be able to choose not to feed your code with any data. In tests it's probably easier to mock it but in production you may choose to bind null input instead of scattering your code with if
s and flags.
compare:
class ComposableReprinter { void reprint(InputStream is) throws IOException { System.out.println(is.read()); } void bla() { reprint(InputStream.nullInputStream()); } }
with this:
class ControllableReprinter { void reprint(InputStream is, boolean for_real) throws IOException { if (for_real) { System.out.println(is.read()); } } void bla() { reprint(new BufferedInputStream(), false); } }
or this:
class NullableReprinter { void reprint(InputStream is) throws IOException { if (is != null) { System.out.println(is.read()); } } void bla() { reprint(null); } }
It makes more sense with output IMHO. Input is probably more for consistency.
This approach is called Null Object: https://en.wikipedia.org/wiki/Null_object_pattern
I see it as a safer (1) and more expressive (2) alternative to initialising a stream variable with null
.
[Output|Input]Stream
is an abstraction. In order to return a null/empty/mock stream, you had to deviate from the core concept down to a specific implementation.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With