The InputStream
class is an abstract class. It contains definitions for all relevant methods, except for one:
public int read() throws IOException
The documentation says:
Reads the next byte of data from the input stream. The value byte is returned as an int in the range 0 to 255. If no byte is available because the end of the stream has been reached, the value -1 is returned.
So an example showing how to create an input stream from an "arbitrary" data source could look like this:
import java.io.IOException;
import java.io.InputStream;
import java.util.function.IntSupplier;
public class DynamicInputStreamExample
{
public static void main(String[] args) throws IOException
{
IntSupplier supplier = () -> methodThatProvidesTheData();
InputStream inputStream = createStream(supplier);
while (true)
{
int read = inputStream.read();
System.out.println("Read " + read + " from stream");
if (read == -1)
{
break;
}
}
}
private static InputStream createStream(IntSupplier supplier)
{
return new InputStream()
{
@Override
public int read() throws IOException
{
return supplier.getAsInt();
}
};
}
// Dummy implementation of a method that provides the data,
// as a sequence of 6 bytes. It returns -1 if no more data
// is available.
private static final int data[] = { 'H', 'e', 'l', 'l', 'o' };
private static int index = 0;
private static int methodThatProvidesTheData()
{
if (index >= data.length)
{
return -1;
}
return data[index++];
}
}
Note: Depending on how your data is generated, it may be beneficial to additionally override other methods of the InputStream
class. Particularly, the read(byte[] b, int off, int len)
method that reads an array of bytes from the source. The main benefit of this would be that your could achieve a (much) higher performance when reading multiple bytes at once. But when this is not relevant for you, then just overriding the int read()
method is sufficient.