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

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

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

  • Reader a InputStream : ReaderInputStream
  • Writer to OutputStream : WriterOutputStream

Devi solo scegliere la codifica della tua scelta.

Se stai iniziando con una stringa puoi anche fare quanto segue:

 new ByteArrayInputStream(inputString.getBytes("UTF-8")) 

Bene, un Reader ha a che fare con i personaggi e un InputStream si occupa dei byte. La codifica specifica come desideri rappresentare i tuoi caratteri come byte, quindi non puoi davvero ignorare il problema. Per quanto riguarda l’evitare problemi, la mia opinione è: scegli un set di caratteri (ad es. “UTF-8”) e segui questo.

Per quanto riguarda effettivamente come fare, come è stato sottolineato, ” i nomi ovvi per queste classi sono ReaderInputStream e WriterOutputStream . ” Sorprendentemente, ” questi non sono inclusi nella libreria Java ” anche se le classi “opposte”, InputStreamReader e OutputStreamWriter sono incluso.

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

  • Apache ReaderInputStream: link diretto al codice sorgente / API
  • Apache WriterOutputStream: link diretto al codice sorgente / API

Come potete vedere, la documentazione di entrambe le classi afferma che “tutte le codifiche di charset supportate da JRE vengono gestite correttamente”.

NB Un commento su una delle altre risposte menziona questo bug . Ma questo riguarda la class Apache Ant ReaderInputStream ( qui ), non la class IO ReaderInputStream di Apache Commons .

Inoltre, se stai iniziando con una String, puoi saltare la creazione di un StringReader e creare un InputStream in un solo passaggio usando org.apache.commons.io.IOUtils da Commons IO in questo modo:

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

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

Uso:

 new CharSequenceInputStream(html, StandardCharsets.UTF_8); 

In questo modo non è necessaria una conversione iniziale in String e quindi in byte[] , che alloca molta più memoria heap, nel caso in cui il report sia di grandi dimensioni. Converte in byte al volo mentre il stream viene letto, direttamente da StringBuffer.

Utilizza CharSequenceInputStream dal progetto IO di Apache Commons.

commons-io 2.0 ha WriterOutputStream

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

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

C’è un RFE, ma è chiuso, non risolverà.

Non è ansible evitare problemi di codifica del testo, ma Apache Commons-io ha

  • ReaderInputStream
  • WriterOutputStream

Nota queste sono le librerie a cui fa riferimento la risposta di Peter su koders.com, solo link alla libreria invece del codice sorgente.

Stai cercando di scrivere il contenuto di un Reader in un OutputStream ? In tal caso, avrai un tempo più facile avvolgere l’ OutputStream in un OutputStreamWriter e scrivere i char dal Reader al Writer , invece di provare a convertire il lettore in un 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 

Un avvertimento quando si utilizza WriterOutputStream – non sempre gestisce la scrittura di dati binari su un file correttamente / come un normale stream di output. Ho avuto un problema con questo che mi ci è voluto un po ‘per rintracciare.

Se ansible, ti consigliamo di utilizzare un stream di output come base e, se hai bisogno di scrivere stringhe, utilizza un wrapper OUtputStreamWriter per lo streaming. È molto più affidabile convertire il testo in byte rispetto al contrario, il che è probabilmente il motivo per cui WriterOutputStream non fa parte della libreria standard di Java

Puoi usare Cactoos (senza metodi statici, solo oggetti):

  • new InputStreamOf(reader)
  • new OutputStreamTo(writer)

Puoi anche convertire il contrario:

  • new ReaderOf(inputStream)
  • new WriterTo(outputStream)

Per leggere una stringa in un stream usando solo ciò che fornisce java.

 InputStream s = new BufferedInputStream( new ReaderInputStream( new StringReader("a string")));