Gravar string no fluxo de saída

139

Eu tenho vários ouvintes de saída que estão implementando OutputStream. Pode ser um PrintStream gravando em stdout ou em um arquivo ou gravando na memória ou em qualquer outro destino de saída; portanto, especifiquei OutputStream como um argumento no método

Agora, eu recebi a String. Qual é a melhor maneira de gravar em fluxos aqui?

Devo apenas usar Writer.write (message.getBytes ())? Posso fornecer bytes, mas se o fluxo de destino for um fluxo de caracteres, ele será convertido automaticamente?

Preciso usar alguns fluxos de pontes aqui?

yart
fonte
2
Não tenho certeza, mas parece que você está tentando reinventar a roda aqui. Você já consultou a Java Base API e a Commons IO API?
Posdef

Respostas:

149

Os fluxos ( InputStreame OutputStream) transferem dados binários . Se você deseja gravar uma sequência em um fluxo, primeiro deve convertê-la em bytes ou, em outras palavras, codificá- la. Você pode fazer isso manualmente (como sugere) usando o String.getBytes(Charset)método, mas evite o String.getBytes()método, porque ele usa a codificação padrão da JVM, que não pode ser prevista com segurança de maneira portátil.

A maneira usual de gravar dados de caracteres em um fluxo, no entanto, é agrupar o fluxo em um Writer(geralmente a PrintWriter), que faz a conversão quando você chama o método write(String)(ou print(String)). O wrapper correspondente para InputStreams é um Reader .

PrintStreamé uma OutputStreamimplementação especial no sentido de que também contém métodos que codificam automaticamente seqüências de caracteres (ele usa um gravador internamente). Mas ainda é um riacho. Você pode agrupar seu fluxo com segurança com um gravador, independentemente de ser uma PrintStreamou outra implementação de fluxo. Não há perigo de codificação dupla.

Exemplo de PrintWriter com OutputStream:

try (PrintWriter p = new PrintWriter(new FileOutputStream("output-text.txt", true))) {
    p.println("Hello");
} catch (FileNotFoundException e1) {
    e1.printStackTrace();
}
MForster
fonte
3
Então, usar PrintWriteré como usar String.getBytes(). Ele usa qualquer codificação aleatória que seja o padrão da JVM. Portanto, só funciona se você tiver sorte.
Christoffer Hammarström
106

OutputStream grava bytes, String fornece caracteres. Você precisa definir Charset para codificar a string em byte []:

outputStream.write(string.getBytes(Charset.forName("UTF-8")));

Mude UTF-8para um conjunto de caracteres de sua escolha.

Peter Knego
fonte
3
Anexe com a seguinte linha. ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
Sahil Patel
32

Você pode criar um empacotamento PrintStream em torno do seu OutputStream e depois chamá-lo print (String):

final OutputStream os = new FileOutputStream("/tmp/out");
final PrintStream printStream = new PrintStream(os);
printStream.print("String");
printStream.close();
Illarion Kovalchuk
fonte
2
Qual conjunto de caracteres o PrintStream está usando para converter em bytes?
Dean Hiller
20

Por design , deve ser feito desta maneira:

OutputStream out = ...;
try (Writer w = new OutputStreamWriter(out, "UTF-8")) {
    w.write("Hello, World!");
} // or w.close(); //close will auto-flush
Antonio
fonte
3
Observe que w.close()fechará outtambém.
Franklin Yu
12

Envolva seu OutputStream com um PrintWriter e use os métodos de impressão nessa classe. Eles pegam uma String e fazem o trabalho para você.

NG.
fonte
9

Você pode usar o Apache Commons IO :

try (OutputStream outputStream = ...) {
    IOUtils.write("data", outputStream, "UTF-8");
}
Felix
fonte
IOUtils.write(String data, OutputStream output, Charset encoding)é implementado como output.write(data.getBytes(Charsets.toCharset(encoding))), por isso pode se um string codificada pode não caber em um array de bytes
Šarūnas