Abstract class InputStream: clients use this to read data from different sources such as file resources using FileInputStream, internet resources using socket.getInputStream or from an in-memory byte array (ByteArrayInputStream). it has methods of int read() which reads one byte and returns an integer ranging from 0 to 255, returns -1 at the end of the file.it blocks until the end of the stream is reached or an exception is thrown. It has another method of public int read (byte[] buffer, int byteOffset, int byteCount) which reads they bytes into a buffer array start from the offset value.
FileInputStream: subclass of InputStream which reads bytes from a file but doesnt buffer the bytes. it implements the read method in InputStream class.
Bufferinputstream wraps the InputStream method, bufferInputStream = new BufferInputStream(inputStream). It will reads the input into the buffer. so if there are frequent access to the data source, it can reduce the access cost.