it-swarm.it

Come convertire un Reader in InputStream e un Writer in OutputStream?

C'è un modo semplice per evitare di affrontare i problemi di codifica del testo?

87
Andrei Savu

Non puoi davvero evitare di affrontare i problemi di codifica del testo, ma ci sono soluzioni esistenti:

Devi solo scegliere la codifica che preferisci.

43
Peter

Se inizi con una stringa, puoi anche fare quanto segue:

new ByteArrayInputStream(inputString.getBytes("UTF-8"))
93
Ritesh Tendulkar

Bene, un Reader si occupa dei personaggi e un InputStream si occupa dei byte. La codifica specifica come desideri rappresentare i tuoi personaggi come byte, quindi non puoi davvero ignorare il problema. Per quanto riguarda evitare problemi, la mia opinione è: scegliere un set di caratteri (ad esempio "UTF-8") e attenersi ad esso.

Per quanto riguarda come farlo, come è stato sottolineato, " i nomi ovvi per queste classi sono ReaderInputStream e WriterOutputStream." Sorprendentemente , " questi non sono inclusi nella Java" anche se le classi 'opposte', InputStreamReader e OutputStreamWriterare incluso.

Quindi, molte persone hanno escogitato le proprie implementazioni, tra cui ApacheCommons IO . A seconda dei problemi di licenza, probabilmente sarai in grado di includere la libreria commons-io nel tuo progetto, o anche copiare una parte del codice sorgente (che è scaricabile qui ).

Come puoi vedere, la documentazione di entrambe le classi afferma che "tutte le codifiche dei set di caratteri supportate da JRE sono gestite correttamente".

N.B. Un commento su una delle altre risposte qui menziona questo bug . Ma ciò influisce sulla classe Apache Ant ​​ReaderInputStream ( qui ), not la classe Apache Commons IO ReaderInputStream.

41
Peter Ford

Si noti inoltre che, se si inizia con una stringa, è possibile saltare la creazione di una StringReader e creare un InputStream in un solo passaggio utilizzando org.Apache.commons.io.IOUtils da Commons IO in questo modo:

InputStream myInputStream = IOUtils.toInputStream(reportContents, "UTF-8");

Ovviamente devi ancora pensare alla codifica del testo, ma almeno la conversione avviene in un solo passaggio.

19
Phil Harvey

Uso:

new CharSequenceInputStream(html, StandardCharsets.UTF_8);

In questo modo non è richiesta una conversione anticipata in String e quindi in byte[], che alloca molta più memoria heap, nel caso in cui il report sia di grandi dimensioni. Si converte in byte al volo durante la lettura dello stream, direttamente da StringBuffer.

Utilizza CharSequenceInputStream da Apache Commons IO.

8
Oliv
7
Bozho

Non puoi evitare problemi di codifica del testo, ma Apache commons-io ha

Nota che queste sono le librerie a cui fa riferimento la risposta di Peter di koders.com, solo collegamenti alla libreria anziché al codice sorgente.

5
dfrankow

I nomi ovvi per queste classi sono ReaderInputStream e WriterOutputStream. Purtroppo questi non sono inclusi nella Java. Tuttavia, google è tuo amico.

Non sono sicuro che risolverà tutti i problemi di codifica del testo, che sono da incubo.

C'è una RFE, ma è Chiusa, non risolverà.

5

Stai cercando di scrivere il contenuto di un Reader su un OutputStream? In tal caso, avrai un tempo più semplice racchiudendo OutputStream in OutputStreamWriter e scrivendo chars da Reader a Writer, invece di provare a convertire il lettore in InputStream:

final Writer writer = new BufferedWriter(new OutputStreamWriter( urlConnection.getOutputStream(), "UTF-8" ) );
int charsRead;
char[] cbuf = new char[1024];
while ((charsRead = data.read(cbuf)) != -1) {
    writer.write(cbuf, 0, charsRead);
}
writer.flush();
// don't forget to close the writer in a finally {} block
4
Sam Barnum

Puoi usare Cactoos (nessun metodo statico, solo oggetti):

Puoi anche convertire il contrario:

1
yegor256

Un avvertimento quando si utilizza WriterOutputStream: non sempre gestisce la scrittura dei dati binari in un file correttamente/lo stesso di un normale flusso di output. Ho avuto un problema con questo che mi ha impiegato un po 'di tempo per rintracciare.

Se possibile, ti consiglio di utilizzare un flusso di output come base e, se devi scrivere stringhe, usa un wrapper OUtputStreamWriter attorno al flusso per farlo. È molto più affidabile convertire il testo in byte rispetto al contrario, motivo per cui WriterOutputStream non fa parte della libreria standard Java

1
romeara