Gibt es eine einfache Möglichkeit, Probleme mit der Textcodierung zu vermeiden?
87
Sie können es nicht wirklich vermeiden, sich mit den Problemen der Textcodierung zu befassen, aber in Apache Commons gibt es bereits Lösungen:
Reader
zu InputStream
:ReaderInputStream
Writer
zu OutputStream
:WriterOutputStream
Sie müssen nur die Codierung Ihrer Wahl auswählen.
Wenn Sie mit einem String beginnen, können Sie auch Folgendes tun:
quelle
ReaderInputStream
Implementierung würde weniger Speicher erfordern - es sollten nicht alle Bytes gleichzeitig in einem Array gespeichert werden müssen.Nun, ein Reader befasst sich mit Zeichen und ein InputStream mit Bytes. Die Codierung 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ählen Sie einen Zeichensatz (z. B. "UTF-8") und bleiben Sie dabei.
Wie bereits erwähnt, lauten die offensichtlichen Namen für diese Klassen ReaderInputStream und WriterOutputStream . Überraschenderweise sind diese nicht in der Java-Bibliothek enthalten , obwohl die entgegengesetzten Klassen InputStreamReader und OutputStreamWriter verwendet werden inbegriffen.
Viele Leute haben sich ihre eigenen Implementierungen ausgedacht, 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 hier heruntergeladen werden kann ).
Wie Sie sehen können, heißt es in der Dokumentation beider Klassen, dass "alle von der JRE unterstützten Zeichensatzcodierungen korrekt behandelt werden".
NB Ein Kommentar zu einer der anderen Antworten hier erwähnt diesen Fehler . Dies betrifft jedoch die Apache Ant ReaderInputStream-Klasse ( hier ) und nicht die Apache Commons IO ReaderInputStream-Klasse.
quelle
Beachten Sie außerdem, dass Sie, wenn Sie mit einem String beginnen, das Erstellen eines StringReader überspringen und in einem Schritt einen InputStream erstellen können, indem Sie org.apache.commons.io.IOUtils von Commons IO wie folgt verwenden :
Natürlich müssen Sie noch über die Textcodierung nachdenken, aber zumindest erfolgt die Konvertierung in einem Schritt.
quelle
new ByteArrayInputStream(report.toString().getBytes("utf-8"))
die Zuweisung von zwei zusätzlichen Kopien des Berichts im Speicher. Wenn der Bericht groß ist, ist er schlecht. Siehe meine Antwort.Verwenden:
Auf diese Weise ist keine Vorabkonvertierung nach
String
und dann nach erforderlichbyte[]
, wodurch viel mehr Heapspeicher zugewiesen wird, falls der Bericht groß ist. Es wird im laufenden Betrieb in Bytes konvertiert, wenn der Stream direkt aus dem StringBuffer gelesen wird.Es verwendet CharSequenceInputStream aus dem Apache Commons IO-Projekt.
quelle
commons-io 2.0 hat
WriterOutputStream
quelle
Die offensichtlichen Namen für diese Klassen sind ReaderInputStream und WriterOutputStream. Leider sind diese nicht in der Java-Bibliothek enthalten. Google ist jedoch dein Freund.
Ich bin mir nicht sicher, ob es alle alptraumhaften Textcodierungsprobleme umgehen wird.
Es gibt eine RFE, jedoch geschlossen ist und nicht behoben werden kann.
quelle
Sie können Probleme mit der Textcodierung nicht vermeiden, Apache commons-io jedoch
Beachten Sie, dass dies die Bibliotheken sind, auf die in Peters Antwort von koders.com Bezug genommen wird, sondern nur Links zur Bibliothek anstelle des Quellcodes.
quelle
Versuchen Sie, den Inhalt von a
Reader
in ein zu schreibenOutputStream
? In diesem Fall fällt es Ihnen leichter , das sOutputStream
in ein zu wickelnOutputStreamWriter
und daschar
s von demReader
in das zu schreibenWriter
, anstatt zu versuchen, den Reader in einen zu konvertierenInputStream
:quelle
Eine Warnung bei Verwendung von WriterOutputStream - das Schreiben von Binärdaten in eine Datei wird nicht immer ordnungsgemäß ausgeführt / genauso wie bei einem normalen Ausgabestream. Ich hatte ein Problem damit, das ich eine Weile brauchte, um es aufzuspüren.
Wenn Sie können, würde ich empfehlen, einen Ausgabestream als Basis zu verwenden. Wenn Sie Zeichenfolgen schreiben müssen, verwenden Sie dazu einen OUtputStreamWriter-Wrapper um den Stream. Das Konvertieren von Text in Bytes ist weitaus zuverlässiger als umgekehrt, weshalb WriterOutputStream wahrscheinlich nicht Teil der Standard-Java-Bibliothek ist
quelle
Sie können Kakteen verwenden (keine statischen Methoden, nur Objekte):
new InputStreamOf(reader)
new OutputStreamTo(writer)
Sie können auch umgekehrt konvertieren:
new ReaderOf(inputStream)
new WriterTo(outputStream)
quelle
Zum Lesen eines Strings in einem Stream mit genau dem, was Java liefert.
quelle