Equivalente de guayaba para IOUtils.toString (InputStream)

Apache Commons IO tiene un buen método de conveniencia IOUtils.toString () para leer un InputStream en una cadena.

Ya que estoy tratando de alejarme de Apache Commons y Guava : ¿hay un equivalente en Guava? Miré todas las clases en el paquete com.google.common.io y no pude encontrar nada tan simple.

Edición: Entiendo y aprecio los problemas con los juegos de caracteres. Sucede que sé que todas mis fonts están en ASCII (sí, ASCII, no ANSI, etc.), así que en este caso, la encoding no es un problema para mí.

Usted indicó en su comentario sobre la respuesta de Calum que iba a usar

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

Este código es problemático porque la sobrecarga CharStreams.toString(Readable) indica:

No cierra la Readable .

Esto significa que su InputStreamReader y, por extensión, el InputStream devuelto por supplier.get() , no se cerrarán una vez que se complete este código.

Si, por otro lado, aprovecha el hecho de que parece que ya tiene un InputSupplier y usó la sobrecarga CharStreams.toString(InputSupplier ), el método toString manejará la creación. y cierre del Reader para usted.

Esto es exactamente lo que Jon Skeet sugirió, excepto que en realidad no hay ninguna sobrecarga de CharStreams.newReaderSupplier que tome un InputStream como entrada … debes darle un InputSupplier :

 InputSupplier supplier = ... InputSupplier readerSupplier = CharStreams.newReaderSupplier(supplier, Charsets.UTF_8); // InputStream and Reader are both created and closed in this single call String text = CharStreams.toString(readerSupplier); 

El punto de InputSupplier es hacer que tu vida sea más fácil al permitir que Guava maneje las partes que requieren un locking feo para asegurar que los recursos se cierren correctamente.

Editar: Personalmente, encuentro lo siguiente (que es como realmente lo escribiría, simplemente estaba desglosando los pasos en el código anterior)

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

ser mucho menos detallado que esto:

 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); } 

Que es más o menos lo que tendrías que escribir para manejar esto correctamente tú mismo.


Edición: febrero de 2014

InputSupplier y OutputSupplier y los métodos que los usan han quedado en desuso en Guava 16.0. Sus reemplazos son ByteSource , CharSource , ByteSink y CharSink . Dado un ByteSource , ahora puede obtener su contenido como una String como esta:

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

Si tienes un Readable , puedes usar CharStreams.toString(Readable) . Entonces, probablemente puedas hacer lo siguiente:

 String string = CharStreams.toString( new InputStreamReader( inputStream, "UTF-8" ) ); 

Te obliga a especificar un juego de caracteres, que supongo que deberías estar haciendo de todos modos.

Casi. Podrías usar algo como esto:

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

Personalmente , no creo que IOUtils.toString(InputStream) sea ​​”agradable”, porque siempre usa la encoding predeterminada de la plataforma, que casi nunca es lo que desea. Hay una sobrecarga que toma el nombre de la encoding, pero usar nombres no es una gran idea de IMO. Es por eso que me gusta Charsets.* .

EDITAR: No es que lo anterior necesite un InputSupplier como streamSupplier . Si ya tienes la transmisión, puedes implementarla con la suficiente facilidad:

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

ACTUALIZACIÓN : Mirando hacia atrás, no me gusta mi solución anterior. Además, es 2013 y ahora hay mejores alternativas disponibles para Java7. Entonces aquí está lo que uso ahora:

 InputStream fis = ...; String text; try ( InputStreamReader reader = new InputStreamReader(fis, Charsets.UTF_8)){ text = CharStreams.toString(reader); } 

o si con InputSupplier

 InputSupplier spl = ... try ( InputStreamReader reader = spl.getInput()){ text = CharStreams.toString(reader); } 

Otra opción es leer los bytes de Stream y crear una cadena a partir de ellos:

 new String(ByteStreams.toByteArray(inputStream)) new String(ByteStreams.toByteArray(inputStream), Charsets.UTF_8) 

No es guava ‘pura’, pero es un poco más corta.

En función de la respuesta aceptada, este es un método de utilidad que se burla del comportamiento de IOUtils.toString() (y una versión sobrecargada con un juego de caracteres, también). Esta versión debe ser segura, ¿verdad?

 public static String toString(final InputStream is) throws IOException{ return toString(is, Charsets.UTF_8); } public static String toString(final InputStream is, final Charset cs) throws IOException{ Closeable closeMe = is; try{ final InputStreamReader isr = new InputStreamReader(is, cs); closeMe = isr; return CharStreams.toString(isr); } finally{ Closeables.closeQuietly(closeMe); } } 

Hay una solución de cierre automático mucho más corta en caso de que la stream de entrada provenga del recurso classpath:

 URL resource = classLoader.getResource(path); byte[] bytes = Resources.toByteArray(resource); String text = Resources.toString(resource, StandardCharsets.UTF_8); 

Utiliza Guava Resources , inspirado en IOExplained .

EDIT (2015): Okio es la mejor abstracción y herramientas para E / S en Java / Android que yo sepa. Lo uso todo el tiempo.

FWIW esto es lo que yo uso.

Si ya tengo un stream en la mano, entonces:

 final InputStream stream; // this is received from somewhere String s = CharStreams.toString(CharStreams.newReaderSupplier(new InputSupplier() { public InputStream getInput() throws IOException { return stream; } }, Charsets.UTF_8)); 

Si estoy creando una secuencia:

 String s = CharStreams.toString(CharStreams.newReaderSupplier(new InputSupplier() { public InputStream getInput() throws IOException { return ; } }, Charsets.UTF_8)); 

Como ejemplo concreto, puedo leer un archivo de texto de Android como este:

 final Context context = ...; String s = CharStreams.toString(CharStreams.newReaderSupplier(new InputSupplier() { public InputStream getInput() throws IOException { return context.getAssets().open("my_asset.txt"); } }, Charsets.UTF_8)); 

Para un ejemplo concreto, así es como puedo leer un archivo de texto de Android activo:

 public static String getAssetContent(Context context, String file) { InputStreamReader reader = null; InputStream stream = null; String output = ""; try { stream = context.getAssets().open(file); reader = new InputStreamReader(stream, Charsets.UTF_8); output = CharStreams.toString(reader); } catch (IOException e) { e.printStackTrace(); } finally { if (stream != null) { try { stream.close(); } catch (IOException e) { e.printStackTrace(); } } if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } } return output; }