Existe-t-il un moyen simple d'éviter de traiter les problèmes de codage de texte?
87
Vous ne pouvez pas vraiment éviter de traiter les problèmes d'encodage de texte, mais il existe des solutions existantes dans Apache Commons:
Reader
à InputStream
:ReaderInputStream
Writer
à OutputStream
:WriterOutputStream
Il vous suffit de choisir l'encodage de votre choix.
Si vous commencez avec une chaîne, vous pouvez également effectuer les opérations suivantes:
la source
ReaderInputStream
implémentation nécessiterait moins de mémoire - il ne devrait pas être nécessaire de stocker tous les octets d'un tableau à la fois.Eh bien, un Reader traite des caractères et un InputStream traite des octets. Le codage spécifie comment vous souhaitez représenter vos caractères sous forme d'octets, vous ne pouvez donc pas vraiment ignorer le problème. Quant à éviter les problèmes, mon avis est le suivant: choisissez un jeu de caractères (par exemple "UTF-8") et respectez-le.
En ce qui concerne la manière de le faire, comme cela a été souligné, « les noms évidents de ces classes sont ReaderInputStream et WriterOutputStream . » Étonnamment, « ils ne sont pas inclus dans la bibliothèque Java » même si les classes «opposées», InputStreamReader et OutputStreamWriter sont inclus.
Ainsi, beaucoup de gens ont mis au point leurs propres implémentations, y compris Apache Commons IO . En fonction des problèmes de licence, vous pourrez probablement inclure la bibliothèque commons-io dans votre projet, ou même copier une partie du code source (qui est téléchargeable ici ).
Comme vous pouvez le voir, la documentation des deux classes indique que «tous les encodages de charset pris en charge par le JRE sont gérés correctement».
NB Un commentaire sur l'une des autres réponses ici mentionne ce bug . Mais cela affecte la classe Apache Ant ReaderInputStream ( ici ), pas la classe Apache Commons IO ReaderInputStream.
la source
Notez également que, si vous commencez avec une chaîne, vous pouvez ignorer la création d'un StringReader et créer un InputStream en une seule étape à l'aide de org.apache.commons.io.IOUtils de Commons IO comme ceci:
Bien sûr, vous devez toujours penser à l'encodage du texte, mais au moins la conversion se fait en une seule étape.
la source
new ByteArrayInputStream(report.toString().getBytes("utf-8"))
, ce qui implique l'allocation de deux copies supplémentaires du rapport en mémoire. Si le rapport est volumineux, il est mauvais. Voyez ma réponse.Utilisation:
Cette méthode ne nécessite pas de conversion initiale vers
String
, puis versbyte[]
, ce qui alloue beaucoup plus de mémoire de tas, au cas où le rapport serait volumineux. Il se convertit en octets à la volée lorsque le flux est lu, directement à partir du StringBuffer.Il utilise CharSequenceInputStream du projet Apache Commons IO.
la source
commons-io 2.0 a
WriterOutputStream
la source
Les noms évidents de ces classes sont ReaderInputStream et WriterOutputStream. Malheureusement, ceux-ci ne sont pas inclus dans la bibliothèque Java. Cependant, Google est votre ami.
Je ne suis pas sûr que cela va contourner tous les problèmes d'encodage de texte, qui sont cauchemardesques.
Il y a un RFE, mais il est fermé, ne résoudra pas.
la source
Vous ne pouvez pas éviter les problèmes d'encodage de texte, mais Apache commons-io a
Notez que ce sont les bibliothèques auxquelles il est fait référence dans la réponse de Peter sur koders.com, juste des liens vers la bibliothèque au lieu du code source.
la source
Essayez-vous d'écrire le contenu d'un
Reader
dans unOutputStream
? Si tel est le cas, vous aurez plus de facilité à encapsuler leOutputStream
dans unOutputStreamWriter
et à écrire lechar
s duReader
vers leWriter
, au lieu d'essayer de convertir le lecteur en unInputStream
:la source
Un avertissement lors de l'utilisation de WriterOutputStream - il ne gère pas toujours l'écriture de données binaires dans un fichier correctement / de la même manière qu'un flux de sortie normal. J'ai eu un problème avec cela qui m'a pris un certain temps à retrouver.
Si vous le pouvez, je vous recommande d'utiliser un flux de sortie comme base, et si vous avez besoin d'écrire des chaînes, utilisez un wrapper OUtputStreamWriter autour du flux pour le faire. Il est beaucoup plus fiable de convertir du texte en octets que l'inverse, ce qui explique probablement pourquoi WriterOutputStream ne fait pas partie de la bibliothèque Java standard
la source
Vous pouvez utiliser Cactoos (pas de méthodes statiques, uniquement des objets):
new InputStreamOf(reader)
new OutputStreamTo(writer)
Vous pouvez également convertir l'inverse:
new ReaderOf(inputStream)
new WriterTo(outputStream)
la source
Pour lire une chaîne dans un flux en utilisant exactement ce que java fournit.
la source