it-swarm-eu.dev

Wie konvertiere ich einen Reader in InputStream und einen Writer in OutputStream?

Gibt es eine einfache Möglichkeit, Probleme mit der Textkodierung zu vermeiden?

87
Andrei Savu

Sie können es nicht wirklich vermeiden, sich mit den Problemen der Textkodierung zu befassen, aber es gibt bereits Lösungen:

Sie müssen nur die Codierung Ihrer Wahl auswählen.

43
Peter

Wenn Sie mit einem String beginnen, können Sie auch Folgendes tun:

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

Nun, ein Reader beschäftigt sich mit Zeichen und ein InputStream mit Bytes. Die Kodierung gibt an, wie Sie Ihre Zeichen als Bytes darstellen möchten, sodass Sie das Problem nicht wirklich ignorieren können. Um Probleme zu vermeiden, ist meine Meinung: Wähle einen Zeichensatz (z. B. "UTF-8") und bleibe dabei.

Wie bereits erwähnt, lauten die offensichtlichen Bezeichnungen für diese Klassen "" ReaderInputStream und WriterOutputStream . "Überraschenderweise" diese sind nicht in der Java library enthalten "obwohl die 'entgegengesetzten' Klassen InputStreamReader und OutputStreamWriter enthalten sind .

Viele Leute haben ihre eigenen Implementierungen entwickelt, einschließlich Apache Commons IO . Abhängig von Lizenzproblemen können Sie wahrscheinlich die Commons-io-Bibliothek in Ihr Projekt aufnehmen oder sogar einen Teil des Quellcodes kopieren (der heruntergeladen werden kann hier ).

Wie Sie sehen, heißt es in der Dokumentation beider Klassen, dass "alle von der JRE unterstützten Zeichensatzkodierungen korrekt behandelt werden".

N.B. Ein Kommentar zu einer der anderen Antworten hier erwähnt dieser Fehler . Aber das betrifft die Apache Ant ReaderInputStream-Klasse ( hier ), nicht den Apache Commons IO ReaderInputStream-Klasse.

41
Peter Ford

Beachten Sie auch, dass Sie, wenn Sie mit einem String beginnen, das Erstellen eines StringReader und eines InputStream in einem Schritt überspringen können, indem Sie org.Apache.commons.io.IOUtils from Commons IO wie folgt verwenden:

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

Natürlich müssen Sie noch über die Textkodierung nachdenken, aber die Konvertierung erfolgt zumindest in einem Schritt.

19
Phil Harvey

Verwenden:

new CharSequenceInputStream(html, StandardCharsets.UTF_8);

Auf diese Weise ist keine vorherige Konvertierung in String und dann in byte[] Erforderlich, wodurch viel mehr Heapspeicher zugewiesen wird, falls der Bericht umfangreich ist. Es konvertiert im laufenden Betrieb in Bytes, wenn der Stream direkt aus dem StringBuffer gelesen wird.

Es verwendet CharSequenceInputStream aus dem Apache Commons IO project.

8
Oliv
7
Bozho

Sie können Probleme mit der Textkodierung nicht vermeiden, aber Apache commons-io hat

Beachten Sie, dass dies die Bibliotheken sind, auf die in Peters Antwort von koders.com verwiesen wird. Es handelt sich lediglich um Links zur Bibliothek anstelle des Quellcodes.

5
dfrankow

Die offensichtlichen Namen für diese Klassen sind ReaderInputStream und WriterOutputStream. Leider sind diese nicht in der Java Bibliothek enthalten. Allerdings ist Google dein Freund.

Ich bin nicht sicher, ob es um alle Probleme mit der Textkodierung gehen wird, die albtraumhaft sind.

Es gibt eine RFE, aber es ist geschlossen, wird nicht behoben.

Versuchen Sie, den Inhalt einer Reader in eine OutputStream zu schreiben? In diesem Fall können Sie die OutputStream leichter in eine OutputStreamWriter einwickeln und die char von der Reader in die Writer, anstatt zu versuchen, den Reader in eine InputStream umzuwandeln:

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

Sie können Cactoos (keine statischen Methoden, nur Objekte) verwenden:

Sie können auch umgekehrt konvertieren:

1
yegor256

Eine Warnung bei der Verwendung von WriterOutputStream - das Schreiben von Binärdaten in eine Datei funktioniert nicht immer ordnungsgemäß/genauso wie bei einem regulären Ausgabestream. Ich hatte ein Problem damit, bei dem ich eine Weile gebraucht habe, um es aufzuspüren.

Wenn Sie können, würde ich empfehlen, einen Ausgabestream als Basis zu verwenden, und wenn Sie Zeichenfolgen schreiben müssen, verwenden Sie einen OUtputStreamWriter-Wrapper um den Stream, um dies zu tun. Das Konvertieren von Text in Bytes ist weitaus zuverlässiger als umgekehrt. Daher ist WriterOutputStream wahrscheinlich nicht Teil der Standardbibliothek Java

1
romeara