A DataOutputStream can wrap a FileOutputStream, but I don’t understand why it has been used here.
FileOutputStream fos = new FileOutputStream(args[0]);
DataOutputStream dos = new DataOutputStream(fos);
dos.writeByte('j');
The last line does the same as fos.write('j'); What does DataOutputStream add in this situation? i.e. why is there?
Streams in Java are defined according to the Decorator design pattern.
This means that you can compose a specific functionality (implemented inside a specific stream class) with another stream. This allows you to customize what you can do with streams. In your specific example
FileOutputStreamis a concrete component which provides the functionality to write to a stream that is mapped to a FileDataOutputStreamis a concrete decorator that, attached to another decorator or component, is able to extend the functionality by giving you a way to write primitives onto the stream, without caring about what there is in the underlying chain of decoration