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.