105 votes

Goyave équivalent pour IOUtils.toString(InputStream)

Apache Commons IO a une belle méthode de convenance IOUtils.toString() pour lire un InputStream d'une Chaîne de caractères.

Depuis que je suis en train d'essayer de s'éloigner de Apache Commons et à la Goyave: existe-il un équivalent dans la Goyave? J'ai regardé toutes les classes de la com.google.common.io paquet et je ne pouvais pas trouver quoi que ce soit presque aussi simple.

Edit: je comprends et j'apprécie les problèmes avec les jeux de caractères. Il se trouve que je sais que toutes mes sources sont en ASCII (oui, ASCII, pas ANSI etc.), donc dans ce cas, l'encodage n'est pas un problème pour moi.

85voto

ColinD Points 48573

Vous avez dit dans votre commentaire sur Calum la réponse que vous allez utiliser

CharStreams.toString(new InputStreamReader(supplier.get(), Charsets.UTF_8))

Ce code est problématique en raison de la surcharge CharStreams.toString(Readable) membres de:

Ne fermez pas l' Readable.

Cela signifie que votre InputStreamReader, et, par extension, InputStream retournée par supplier.get(), ne sera pas fermé après cette fin du code.

Si, d'autre part, vous profitez du fait que vous semblez déjà avoir un InputSupplier<InputStream> et utilisé la surcharge CharStreams.toString(InputSupplier<R extends Readable & Closeable>), l' toString méthode permettra de gérer à la fois la création et la fermeture de l' Reader pour vous.

C'est exactement ce que Jon Skeet suggéré, sauf qu'il n'y a pas réellement une surcharge de CharStreams.newReaderSupplier qui prend un InputStream comme entrée... vous devez donner un InputSupplier:

InputSupplier<? extends InputStream> supplier = ...
InputSupplier<InputStreamReader> readerSupplier = 
    CharStreams.newReaderSupplier(supplier, Charsets.UTF_8);

// InputStream and Reader are both created and closed in this single call
String text = CharStreams.toString(readerSupplier);

Le point de InputSupplier est de rendre votre vie plus facile en permettant de Goyave pour gérer les pièces qui nécessitent un vilain try-finally block pour s'assurer que les ressources sont correctement fermé.

Edit: Personnellement, je trouve le suivant (qui est de savoir comment j'avais fait de l'écrire, c'était juste en décomposant les étapes décrites dans le code ci-dessus)

String text = CharStreams.toString(
    CharStreams.newReaderSupplier(supplier, Charsets.UTF_8));

à être beaucoup moins verbeux que ceci:

String text;
InputStreamReader reader = new InputStreamReader(supplier.get(), 
    Charsets.UTF_8);
boolean threw = true;
try {
  text = CharStreams.toString(reader);
  threw = false;
}
finally {
  Closeables.close(reader, threw);
}

Ce qui est plus ou moins ce que vous devriez écrire pour gérer cela correctement vous-même.


Edit: Févr. 2014

InputSupplier et OutputSupplier et les méthodes qui les utilisent ont été désapprouvées dans la Goyave 16.0. Leurs remplaçants sont ByteSource, CharSource, ByteSink et CharSink. Étant donné un ByteSource, vous pouvez maintenant obtenir son contenu en tant que String comme ceci:

ByteSource source = ...
String text = source.asCharSource(Charsets.UTF_8).read();

56voto

Calum Points 3160

Si vous avez un vous pouvez utiliser . Ainsi, vous pouvez probablement faire ce qui suit :

Vous oblige à spécifier un jeu de caractères, ce qui je suppose que vous devriez faire de toute façon.

16voto

husayt Points 4384

Mise à jour: regarder en arrière, je n’aime pas mon ancienne solution. D’ailleurs c’est 2013 maintenant et il existe de meilleures alternatives disponible pour Java7. Voici donc ce que j’utilise maintenant :

ou si avec InputSupplier

15voto

Jon Skeet Points 692016

Près de. Vous pouvez utiliser quelque chose comme ceci:

InputSupplier<InputStreamReader> readerSupplier = CharStreams.newReaderSupplier
    (streamSupplier, Charsets.UTF_8);
String text = CharStreams.toString(readerSupplier);

Personnellement, je ne pense qu' IOUtils.toString(InputStream) est "nice" - parce qu'il utilise toujours l'encodage par défaut de la plate-forme, qui n'est presque jamais ce que vous voulez. Il y a une surcharge qui prend le nom de l'encodage, mais en utilisant des noms n'est pas une bonne idée de l'OMI. C'est pourquoi j'aime Charsets.*.

EDIT: Pas que les besoins ci-dessus une InputSupplier<InputStream> le streamSupplier. Si vous avez déjà les cours d'eau, vous pouvez la mettre assez facilement:

InputSupplier<InputStream> supplier = new InputSupplier<InputStream>() {
    @Override public InputStream getInput() {
        return stream;
    }
};

11voto

ponomandr Points 575

Une autre option consiste à lire des octets du flux de données et créer une chaîne d’eux :

Il n’est pas goyave « pure », mais c’est un peu plus court.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X