A string is basically stored in memory; its contents are completely available at the time you receive the String
instance. You can directly search the string or find other information - such as the length - of the string.
If you receive a Reader
instance you don't know the size of the string, and many functions such as searching are not (directly) available. On the other hand, you don't need to store the entire string in memory.
Moreover, not all of the contents need to be available at the time you receive the Reader
instance. A good example is receiving text over a socket; you may want to handle part of the contents when they are received, not after the full message is received.
The complete output of an application - in your example code - may also not be directly available; your method blocks until it is (i.e. until your fullCommand
application exits).
If you want to return a character stream you can simply return the BufferedReader
instance. If it makes sense to return a binary stream from a Reader
most of the time, but if this is required then read this answer.
EDIT: if you just need binary you should of course directly return p.getInputStream()
in your example.