1. Información general
En este tutorial rápido, aprenderemos cómo escribir un InputStream de Java en un OutputStream de Java . Primero usaremos la funcionalidad principal de Java 8 y Java 9. Luego, veremos un par de bibliotecas externas: Guava y la biblioteca IO de Apache Commons.
Los métodos de utilidad proporcionados por Java 9, Guava y Apache Commons IO no vacían ni cierran los flujos. Entonces, necesitaremos administrar estos recursos usando try-with-resources o un bloque finalmente .
2. Usando Java 8
Primero, comenzaremos por crear un método simple usando Java vanilla para copiar el contenido de InputStream a OutputStream :
void copy(InputStream source, OutputStream target) throws IOException { byte[] buf = new byte[8192]; int length; while ((length = source.read(buf)) > 0) { target.write(buf, 0, length); } }
Este código es bastante sencillo: simplemente leemos algunos bytes y luego los escribimos.
3. Usando Java 9
Java 9 proporciona un método de utilidad, InputStream.transferTo () , para esta tarea .
Veamos cómo usaríamos el método transferTo () :
@Test public void givenUsingJavaNine_whenCopyingInputStreamToOutputStream_thenCorrect() throws IOException { String initialString = "Hello World!"; try (InputStream inputStream = new ByteArrayInputStream(initialString.getBytes()); ByteArrayOutputStream targetStream = new ByteArrayOutputStream()) { inputStream.transferTo(targetStream); assertEquals(initialString, new String(targetStream.toByteArray())); } }
Tenga en cuenta que cuando se trabaja con flujos de archivos, es más eficiente usar Files.copy () que el método transferTo () .
4. Usando guayaba
A continuación, veamos cómo usaríamos el método de utilidad ByteStreams.copy () de Guava .
Necesitaremos incluir la dependencia de guayaba en nuestro pom.xml :
com.google.guava guava 29.0-jre
Creemos un caso de prueba simple para mostrar cómo podríamos usar ByteStreams para copiar datos:
@Test public void givenUsingGuava_whenCopyingInputStreamToOutputStream_thenCorrect() throws IOException { String initialString = "Hello World!"; try (InputStream inputStream = new ByteArrayInputStream(initialString.getBytes()); ByteArrayOutputStream targetStream = new ByteArrayOutputStream()) { ByteStreams.copy(inputStream, targetStream); assertEquals(initialString, new String(targetStream.toByteArray())); } }
5. Uso de Commons IO
Finalmente, veamos cómo usaríamos el método Commons IO IOUtils.copy () para esta tarea.
Por supuesto, necesitaremos agregar la dependencia commons-io al pom.xml :
commons-io commons-io 2.7
Creemos un caso de prueba simple usando IOUtils para copiar datos del flujo de entrada al flujo de salida:
@Test public void givenUsingCommonsIO_whenCopyingInputStreamToOutputStream_thenCorrect() throws IOException { String initialString = "Hello World!"; try (InputStream inputStream = new ByteArrayInputStream(initialString.getBytes()); ByteArrayOutputStream targetStream = new ByteArrayOutputStream()) { IOUtils.copy(inputStream, targetStream); assertEquals(initialString, new String(targetStream.toByteArray())); } }
Nota: Commons IO proporciona métodos adicionales para trabajar con InputStream sy OutputStream s. IOUtils.copyLarge () debe usarse siempre que sea necesario copiar 2 GB o más de datos.
6. Conclusión
En este artículo, exploramos formas sencillas de copiar datos de un InputStream a un OutputStream .
La implementación de estos ejemplos está disponible en GitHub.