Has to be InputStream!
- skip() returns a long requiring you to use a while loop every time you skip
- read(byte[]) overloads require you to bring your own array which creates data ownership problems
- no-argument read() is useless, and requires implementing at least two read() overloads in subclasses
- available()/mark()/markSupported()/reset() methods shouldn't be a part of this interface
- Decorators like DataInputStream and InputStreamReader can't be combined so you have to pick either byte or char interpretation, not both.
- Multiple decorators require copying between intermediate layers instead of just being able to move ownership of bytes.