Java: Diferença entre PrintStream e PrintWriter


125

Qual é a diferença entre PrintStreame PrintWriter? Eles têm muitos métodos em comum, devido aos quais eu costumo misturar essas duas classes. Além disso, acho que podemos usá-los exatamente para as mesmas coisas. Mas tem que haver uma diferença, caso contrário, haveria apenas uma classe.

Pesquisei nos arquivos, mas não consegui encontrar esta pergunta.


1
+1 Boa pergunta, eu também misturo essas duas classes, e o documento da API também não ajuda muito.
Helpermethod

Outra diferença é como o autoflush funciona. Para um escritor, a presença de um caractere \ n na saída aciona flush (). Mas em um fluxo de bytes (PrintStream), existem apenas bytes. autoflush funciona como descrito em Javadoc, com base em: "própria noção de separador de linha da plataforma, em vez do caractere de nova linha".
mins

Respostas:


129

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.)


3
Foi o que pensei também - mas não é verdade. Até o PrintStream mantém um gravador sob o capô - se você passar um OutputStream, ele o envolverá.
Jon Skeet

3
@ Jon - internamente, existe um Writer, mas ele grava em um OutputStream, portanto o efeito líquido é que um PrintStream grava em um OutputStream - a conversão de char para byte acontece e usa a codificação da plataforma padrão. Não existe esse requisito para a conversão de caracteres em um PrintWriter; você pode ficar com os caracteres o tempo todo.
Mdma

"O conjunto de caracteres padrão é determinado durante a inicialização da máquina virtual e normalmente depende do código de idioma e conjunto de caracteres do sistema operacional subjacente.", Também Locale altera o conjunto de caracteres padrão em algumas plataformas.
Pindatjuh

7
Desde o Java 1.5, PrintStreamnão se limita ao uso da codificação padrão da plataforma; existem construtores que aceitam um nome de conjunto de caracteres. Assim, as distinções entre PrintStreame PrintWritersão que a PrintWriternão pode escrever bytes brutos e as duas classes agrupam tipos diferentes de destinos.
Ted Hopp

1
Também pode valer a pena notar uma diferença significativa no comportamento deles, enquanto eles compartilham efetivamente os métodos de uma interface PrintStream. print()São funções de conveniência que chamam write(); portanto, elas acionam o autoflush se ativado. PrintWriterpor outro lado, não será liberado automaticamente após uma chamada para print(). Eu tenho demonstrado alguns iniciantes em Java hoje e isso chamou a atenção de alguns estudantes que não estavam familiarizados com a necessidade de liberar manualmente. Caso contrário, sua resposta é ótima.
Robadob

61

Com o que PrintStreamvocê está preso à codificação padrão da plataforma.

PrintStream stream = new PrintStream(output);

Com o PrintWritervocê pode, no entanto, passar um OutputStreamWritercom uma codificação específica.

PrintWriter writer = new PrintWriter(new OutputStreamWriter(output, "UTF-8"));

A vantagem é que você pode controlar o código que os caracteres devem ser escritos, para que não acabem como mojibake .


12
Desde 1.4, há um novo construtor para PrintStream que leva a codificaçãoPrintStream(OutputStream out, boolean autoFlush, String encoding)
artbristol

19

Desde o JDK 1.4, é possível especificar a codificação de caracteres para um PrintStream. Portanto, as diferenças entre PrintStream e PrintWriter são apenas sobre o comportamento de liberação automática e que um PrintStream não pode quebrar um Writer.


3

Escritores como PrintWriter são para saída de texto, fluxos são para saída binária. Os escritores lidam com coisas do conjunto de caracteres para você. Os fluxos não o fazem porque se supõe que você não deseja esse tipo de conversão, o que prejudicaria seus dados binários e, se você preferir, usaria um gravador.


1
Exceto PrintStream, porque esse leva uma codificação para que possa lidar com um pouco mais do que um OutputStream padrão.
Simon Groenewolt

Parece estranho que o System.out, cujo único objetivo seja imprimir strings, seja realmente um PrintStream.
minutos

"Os gravadores manipulam coisas do conjunto de caracteres para você" - apenas os gravadores que lidam com a conversão de caracteres em bytes. Nem todos os escritores fazem.
Aivar

2

Você pode gravar bytes não processados ​​em um fluxo e não em um gravador. O javadoc PrintWriter lista as outras diferenças (o mais importante é poder definir uma codificação em um fluxo para que ele possa interpretar os bytes brutos que eu diria).


Com PrintStream Pode-se especificar codificação bem
Aivar

1

do núcleo java por Horstmann

Os veteranos de Java podem se perguntar o que aconteceu com a classe PrintStream e com o System.out. No Java 1.0, a classe PrintStream simplesmente truncou todos os caracteres Unicode para caracteres ASCII, descartando o byte superior. (Na época, o Unicode ainda era uma codificação de 16 bits.) Claramente, essa não era uma abordagem limpa ou portátil, e foi corrigida com a introdução de leitores e gravadores no Java 1.1. Para compatibilidade com o código existente, System.in, System.out e System.err ainda são fluxos de entrada / saída, não leitores e gravadores. Mas agora a classe PrintStream converte internamente caracteres Unicode na codificação de host padrão da mesma maneira que o PrintWriter. Objetos do tipo PrintStream agem exatamente como gravadores de impressão quando você usa os métodos print e println,


-3

O Printwriter é um aprimoramento do fluxo de impressão.

IE imprime o fluxo para uma finalidade específica.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.