Convertir InputStream a String

JavaJavaBeginner
Practicar Ahora

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

En Java, la clase InputStream se utiliza para leer datos de archivos en una secuencia ordenada. Para utilizar los datos como una cadena, necesitamos convertir el InputStream en una cadena. Esta práctica te enseñará diferentes maneras de convertir un InputStream en una cadena.

Usando InputStreamReader

La clase InputStreamReader proporciona un método read() para leer datos de un InputStream en una matriz de caracteres. Podemos convertir la matriz de char en una cadena. Crea un nuevo archivo fuente Java InputStreamToString.java en el directorio ~/project con el siguiente contenido:

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class InputStreamToString {
    public static String inputStreamToString(InputStream input) throws IOException {
        InputStreamReader reader = new InputStreamReader(input);
        char[] charArray = new char[256];
        reader.read(charArray);
        return new String(charArray);
    }

    public static void main(String[] args) {
        try {
            InputStream input = new ByteArrayInputStream("hello world".getBytes());
            String strFromInputStream = inputStreamToString(input);
            System.out.print("String from the Input Stream is: " + strFromInputStream);
        } catch(Exception e) {
            System.out.print(e);
        }
    }
}

Para ejecutar el código, abre la terminal y luego compila y ejecuta el código con el siguiente comando:

javac InputStreamToString.java && java InputStreamToString

Usando InputStreamReader y BufferedReader con StringBuilder

El paso anterior puede ser ineficiente para entradas más grandes. En cambio, podemos usar un BufferedReader para envolver el InputStreamReader para mejorar la eficiencia. Luego, usaremos un objeto StringBuilder para agregar las líneas leídas del BufferedReader. Crea un nuevo paso en InputStreamToString.java después del Paso 1 con el siguiente código:

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class InputStreamToString {
    public static String inputStreamToString(InputStream input) throws IOException {
        StringBuilder builder = new StringBuilder();
        InputStreamReader reader = new InputStreamReader(input);
        BufferedReader bufferedReader = new BufferedReader(reader);
        String line;
        while ((line = bufferedReader.readLine())!= null) {
            builder.append(line);
        }
        return builder.toString();
    }

    public static void main(String[] args) {
        try {
            InputStream input = new ByteArrayInputStream("hello world".getBytes());
            String strFromInputStream = inputStreamToString(input);
            System.out.print("String from the Input Stream is: " + strFromInputStream);
        } catch(Exception e) {
            System.out.print(e);
        }
    }
}

Usando InputStreamReader y BufferedReader sin StringBuilder

Podemos utilizar un enfoque más simple al usar el método lines() de la clase BufferedReader. Esto nos permite omitir la adición de cada línea a una instancia separada de StringBuilder. Crea un nuevo paso en InputStreamToString.java después del Paso 2 con el siguiente código:

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.stream.Collectors;

public class InputStreamToString {
    public static String inputStreamToString(InputStream input) throws IOException {
        InputStreamReader reader = new InputStreamReader(input);
        BufferedReader bufferedReader = new BufferedReader(reader);
        String str = bufferedReader.lines().collect(Collectors.joining("\n"));
        return str;
    }

    public static void main(String[] args) {
        InputStream input = new ByteArrayInputStream("hello world".getBytes());
        String strFromInputStream = inputStreamToString(input);
        System.out.print("String from the Input Stream is: " + strFromInputStream);
    }
}

Usando el método readAllBytes() del InputStream

La clase InputStream introdujo el método readAllBytes() en Java 9. Esto puede convertir eficientemente el objeto InputStream completo en una cadena en una sola línea de código. Sin embargo, este método no se recomienda para entradas más grandes. Crea un nuevo paso en InputStreamToString.java después del Paso 3 con el siguiente código:

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

public class InputStreamToString {
    public static String inputStreamToString(InputStream input) throws IOException {
        return new String(input.readAllBytes());
    }

    public static void main(String[] args) {
        try {
            InputStream input = new ByteArrayInputStream("hello world".getBytes());
            String strFromInputStream = inputStreamToString(input);
            System.out.print("String from the Input Stream is: " + strFromInputStream);
        } catch(Exception e) {
            System.out.print(e);
        }
    }
}

Usando la clase Scanner

También podemos usar la clase Scanner, una clase comúnmente utilizada para leer y analizar datos, para convertir el flujo de entrada en una cadena. Crea un nuevo paso en InputStreamToString.java después del Paso 4 con el siguiente código:

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;

public class InputStreamToString {
    public static String inputStreamToString(InputStream input) throws IOException {
        Scanner scanner = new Scanner(input);
        StringBuilder builder = new StringBuilder();
        while (scanner.hasNext()) {
            builder.append(scanner.nextLine());
        }
        return builder.toString();
    }

    public static void main(String[] args) {
        try {
            InputStream input = new ByteArrayInputStream("hello world".getBytes());
            String strFromInputStream = inputStreamToString(input);
            System.out.print("String from the Input Stream is: " + strFromInputStream);
        } catch(Exception e) {
            System.out.print(e);
        }
    }
}

Usando ByteArrayOutputStream

Podemos usar la clase ByteArrayOutputStream del paquete java.io y copiar datos desde el flujo de entrada hacia el arreglo de bytes. Luego, podemos escribir el arreglo de bytes en el ByteArrayOutputStream. Finalmente, usaremos el método toString() del ByteArrayOutputStream para obtener la representación en cadena. Crea un nuevo paso en InputStreamToString.java después del Paso 5 con el siguiente código:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class InputStreamToString {
    public static String inputStreamToString(InputStream input) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[128];
        int length;
        while ((length = input.read(buffer))!= -1) {
            byteArrayOutputStream.write(buffer, 0, length);
        }
        return byteArrayOutputStream.toString();
    }

    public static void main(String[] args) {
        try {
            InputStream input = new ByteArrayInputStream("hello world".getBytes());
            String strFromInputStream = inputStreamToString(input);
            System.out.print("String from the Input Stream is: " + strFromInputStream);
        } catch(Exception e) {
            System.out.print(e);
        }
    }
}

Usando el paquete java.nio

En el paquete java.nio, podemos crear un archivo temporal usando Files.createTempFile y copiar los datos desde el InputStream hacia este archivo. Luego, podemos leer el contenido de este archivo temporal en una cadena. Crea un nuevo paso en InputStreamToString.java después del Paso 6 con el siguiente código:

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;

public class InputStreamToString {
    public static String inputStreamToString(InputStream input) throws IOException {
        Path file = Files.createTempFile(null, null);
        Files.copy(input, file, StandardCopyOption.REPLACE_EXISTING);
        return new String(Files.readAllBytes(file));
    }

    public static void main(String[] args) {
        try {
            InputStream input = new ByteArrayInputStream("hello world".getBytes());
            String strFromInputStream = inputStreamToString(input);
            System.out.print("String from the Input Stream is: " + strFromInputStream);
        } catch(Exception e) {
            System.out.print(e);
        }
    }
}

Usando la biblioteca Google Guava

La biblioteca Google Guava proporciona la clase CharStreams para convertir un InputStream en una cadena. Podemos usar el método toString() de esta clase para hacer esto. Tomará un objeto Readable (como el InputStreamReader) y leerá los datos de él en una cadena. Crea un nuevo paso en InputStreamToString.java después del Paso 7 con el siguiente código:

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import com.google.common.io.CharStreams;

public class InputStreamToString {
    public static String inputStreamToString(InputStream input) throws IOException {
        try(InputStreamReader reader = new InputStreamReader(input)) {
            return CharStreams.toString(reader);
        }
    }

    public static void main(String[] args) {
        try {
            InputStream input = new ByteArrayInputStream("hello world".getBytes());
            String strFromInputStream = inputStreamToString(input);
            System.out.print("String from the Input Stream is: " + strFromInputStream);

        } catch(Exception e) {
            System.out.print(e);
        }
    }
}

Usando Apache Commons IO

La clase IOUtils del paquete org.apache.commons.io también contiene un método toString(). Podemos pasar directamente el objeto InputStream a este método, y éste leerá los datos de él y los convertirá en una cadena. También debemos especificar una Charset. Crea un nuevo paso en InputStreamToString.java después del Paso 8 con el siguiente código:

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import org.apache.commons.io.IOUtils;

public class InputStreamToString {
    public static void main(String[] args) {
        try {
            InputStream input = new ByteArrayInputStream("hello world".getBytes());
            String strFromInputStream = IOUtils.toString(input, StandardCharsets.UTF_8.name());
            System.out.print("String from the Input Stream is: " + strFromInputStream);

        } catch(Exception e) {
            System.out.print(e);
        }
    }
}

Usando la clase StringWriter con Apache Commons IO

Podemos usar la clase StringWriter del paquete java.io y copiar el contenido del InputStream en el StringWriter. Usaremos el método copy() de la clase IOUtils. Crea un nuevo paso en InputStreamToString.java después del Paso 9 con el siguiente código:

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import org.apache.commons.io.IOUtils;

public class InputStreamToString {
    public static void main(String[] args) {
        try {
            InputStream input = new ByteArrayInputStream("hello world".getBytes());
            StringWriter sw = new StringWriter();
            IOUtils.copy(input, sw, StandardCharsets.UTF_8.name());
            String strFromInputStream = sw.toString();
            System.out.print("String from the Input Stream is: " + strFromInputStream);

        } catch(Exception e) {
            System.out.print(e);
        }
    }
}

Resumen

En este laboratorio, aprendiste diferentes maneras de convertir un InputStream en una cadena en Java. Puedes usar la clase ByteArrayOutputStream o la clase BufferedReader para mejorar la eficiencia. La clase Scanner también está disponible para convertir el flujo de entrada en una cadena. El método readAllBytes() es adecuado solo para entradas más pequeñas. Podemos usar bibliotecas externas como Google Guava o Apache Commons IO para simplificar el proceso. Recuerda manejar las excepciones y cerrar el InputStream para evitar fugas de recursos.