Isso pode parecer irreverente, mas PrintStreamimprime em um OutputStreame PrintWriterimprime em um Writer. Ok, duvido que receba algum argumento por afirmar o óbvio. Mas tem mais.
Então, qual é a diferença entre an OutputStreame a Writer? Ambos são fluxos, sendo a principal diferença a OutputStreamum fluxo de bytes, enquanto a Writeré um fluxo de caracteres.
Se um OutputStreamlida com bytes, o que dizer PrintStream.print(String)? Ele converte caracteres em bytes usando a codificação da plataforma padrão. Usar a codificação padrão geralmente é uma coisa ruim, pois pode levar a erros ao passar de uma plataforma para outra, especialmente se você estiver gerando o arquivo em uma plataforma e consumindo-o em outra.
Com a Writer, você normalmente especifica a codificação a ser usada, evitando dependências da plataforma.
Por que se preocupar em ter um PrintStreamno JDK, já que a intenção principal é escrever caracteres, e não bytes? PrintStreamé anterior ao JDK 1.1 quando os fluxos de caracteres do Reader / Writer foram introduzidos. Eu imagino que a Sun teria se tornado obsoleta PrintStreamse fosse tão amplamente usada. (Afinal, você não deseja que cada chamada System.outgere um aviso de API descontinuado! Além disso, alterar o tipo de PrintStreampara PrintWriternos fluxos de saída padrão teria quebrado os aplicativos existentes.)