If I want to write some arbitrary binary data, can I use PrintWriter instead of OutputStream? I see the PrintWriter does have the write() method although it doesn't have one taking byte/byte arguments. If I want to write some binary data, can I just write it using write(int c)?
In short what are the difference between PrintWriter and OutputSteam?
Writer and Reader classes deal with textual characters (type char) and do some translation between Unicode and the real platform's file encoding. Stream classes deal in binary data (type byte), and do no such translation. So the answer is no, if you want to write binary data, don't use any Writer class; use an OutputStream of some kind.
Here is a nice tutorial which teaches you all about these classes, their relationships, and their uses.