web-dev-qa-db-fra.com

Comment convertir un lecteur en InputStream et un graveur en OutputStream?

Existe-t-il un moyen simple d'éviter de traiter les problèmes de codage de texte?

87
Andrei Savu

Vous ne pouvez pas vraiment éviter de traiter les problèmes d'encodage de texte, mais il existe des solutions existantes:

Il vous suffit de choisir le codage de votre choix.

43
Peter

Si vous commencez avec une chaîne, vous pouvez également procéder comme suit:

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

Eh bien, un lecteur traite les caractères et un InputStream traite les octets. Le codage spécifie comment vous souhaitez représenter vos caractères sous forme d'octets, vous ne pouvez donc pas ignorer le problème. Pour éviter les problèmes, mon avis est le suivant: choisissez un jeu de caractères (par exemple, "UTF-8") et respectez-le.

Comme cela a été souligné, " les noms évidents pour ces classes sont ReaderInputStream et WriterOutputStream . "Étonnamment," ceux-ci ne sont pas inclus dans la Java bibliothèque "Même si les classes 'opposées', InputStreamReader et OutputStreamWriter sont inclus.

Donc, beaucoup de gens ont mis au point leurs propres implémentations, y compris Apache Commons IO . Selon les 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 (téléchargeable ici ).

Comme vous pouvez le constater, la documentation des deux classes indique que "tous les codages de jeux de caractères pris en charge par le JRE sont gérés correctement".

N.B. Un commentaire sur l'une des autres réponses ici mentionne ce bug . Mais cela affecte la classe ApIn Ant ReaderInputStream ( ici ), pas Apache Commons IO Classe ReaderInputStream.

41
Peter Ford

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 étape à l'aide de org.Apache.commons.io.IOUtils à partir de Commons IO comme suit:

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

Bien sûr, vous devez encore penser au codage du texte, mais au moins la conversion se fait en une étape.

19
Phil Harvey

Utilisation:

new CharSequenceInputStream(html, StandardCharsets.UTF_8);

Cette méthode ne nécessite pas de conversion initiale en String, puis en byte[], qui alloue beaucoup plus de mémoire, si le rapport est volumineux. Il se convertit en octets à la volée au fur et à mesure que le flux est lu, directement à partir du StringBuffer.

Il utilise CharSequenceInputStream d’Apache Commons IO projet.

8
Oliv
7
Bozho

Vous ne pouvez pas éviter les problèmes de codage de texte, mais Apache commons-io a

Notez que ce sont les bibliothèques mentionnées dans la réponse de Peter de koders.com, juste des liens vers la bibliothèque au lieu du code source.

5
dfrankow

Les noms évidents pour ces classes sont ReaderInputStream et WriterOutputStream. Malheureusement, ils ne sont pas inclus dans la bibliothèque Java. Cependant, Google est votre ami.

Je ne suis pas sûr qu'il va régler tous les problèmes d'encodage de texte, qui sont cauchemardesques.

Il y a un RFE, mais c'est Fermé, ça ne va pas s'arranger.

5

Essayez-vous d'écrire le contenu d'un Reader dans un OutputStream? Si c'est le cas, vous aurez plus de facilité à encapsuler le OutputStream dans un OutputStreamWriter et à écrire le chars du Reader au Writer au lieu d'essayer de convertir le lecteur en 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

Vous pouvez utiliser Cactoos (pas de méthodes statiques, seulement des objets):

Vous pouvez également convertir l’inverse:

1
yegor256

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 à traquer.

Si vous le pouvez, je vous recommanderais d'utiliser un flux de sortie comme base et, si vous devez écrire des chaînes, utilisez un encapsuleur OUtputStreamWriter autour du flux pour le faire. Il est beaucoup plus fiable de convertir du texte en octets que l’inverse, raison pour laquelle WriterOutputStream ne fait pas partie du standard Java library

1
romeara