Clase InputStream de Java

InputStream es la clase base abstracta del sistema Java I/O utilizada para leer datos de bytes, ubicada enjava.ioel paquete.

InputStream es la superclase de todos los flujos de entrada de bytes y proporciona el marco básico para leer datos de bytes.

InputStream es una clase abstracta, lo que significa que no puedes instanciarla directamente, pero puedes crear objetos de flujo de entrada concretos a través de sus subclases (como FileInputStream, ByteArrayInputStream, etc.).


Análisis de los métodos principales

InputStream es parte de los flujos IO de Java y se utiliza para leer datos byte a byte (8 bits).

InputStream es adecuado para procesar datos de tipo no textual, como imágenes, audio, video, archivos comprimidos, etc.

Puedes imaginarlo como una "tubería de agua": los datos fluyen desde el origen hasta tu programa como el agua.

Métodos principales

Nombre del métodoDescripción de la función
int read()Lee un byte, el valor de retorno es un int de 0~255, si se llega al final del flujo devuelve-1
int read(byte[] b)Lee como máximo del flujob.lengthbytes de datos y los almacena en un array de bytesb
int read(byte[] b, int off, int len)desdeoffLee como máximo desde la posición de desplazamientolenbytes al arrayb
void close()Cierra el flujo y libera los recursos asociados

Leer un solo byte

public abstract int read() throws IOException

Este es el método más básico de InputStream, se utiliza para leer el siguiente byte de datos del flujo de entrada. El valor de retorno es un int entre 0 y 255, si se llega al final del flujo devuelve -1.

Código de ejemplo

Ejemplo

InputStream input = new FileInputStream("example.txt");
int data = input.read();
while(data != -1) {
    System.out.print((char)data);
    data = input.read();
}
input.close();

Leer array de bytes

Ejemplo

public int read(byte[] b) throws IOException

Este método intenta leer como máximo b.length bytes de datos en el array de bytes, devuelve el número de bytes realmente leídos, si se llega al final del flujo devuelve -1.

Código de ejemplo

Ejemplo

InputStream input = new FileInputStream("example.txt");
byte[] buffer = new byte[1024];
int bytesRead;
while((bytesRead = input.read(buffer)) != -1) {
    System.out.println("Read " + bytesRead + " bytes");
}
input.close();

, leer como máximo 500 bytes

Ejemplo

public int read(byte[] b, int off, int len) throws IOException

Este método te permite especificar desde qué posición comenzar a almacenar los datos leídos (off), y cuántos bytes leer como máximo (len).

Código de ejemplo

Ejemplo

InputStream input = new FileInputStream("example.txt");
byte[] buffer = new byte[1024];
int bytesRead = input.read(buffer, 10, 500); // Almacenar desde buffer
input.close();

Saltar bytes

Ejemplo

public long skip(long n) throws IOException

Salta y descarta n bytes de datos del flujo de entrada, devuelve el número real de bytes saltados.

Comprobar bytes disponibles

Ejemplo

public int available() throws IOException

Devuelve el número estimado de bytes que se pueden leer (o saltar) de este flujo de entrada sin bloquearse.

2.6 Cerrar el flujo

Ejemplo

public void close() throws IOException

Cierra el flujo de entrada y libera todos los recursos del sistema asociados a él. Este es un método muy importante y debe llamarse después de completar las operaciones del flujo.


Introducción a las subclases comunes

  • FileInputStream: Se utiliza para leer datos de un archivo.
  • ByteArrayInputStream: Permite que un array de bytes en memoria actúe como flujo de entrada.
  • FilterInputStream: Clase decoradora que proporciona funcionalidades adicionales a otros flujos de entrada.
  • ObjectInputStream: Se utiliza para deserializar objetos previamente serializados con ObjectOutputStream.
  • PipedInputStream: Se utiliza junto con PipedOutputStream para implementar comunicación por tuberías entre hilos.

Buenas prácticas

Usar try-with-resources

Java 7 introdujo la sentencia try-with-resources, que puede cerrar automáticamente los recursos que implementan la interfaz AutoCloseable.

Ejemplo

try (InputStream input = new FileInputStream("example.txt")) {
    int data;
    while ((data = input.read()) != -1) {
        System.out.print((char)data);
    }
} catch (IOException e) {
    e.printStackTrace();
}

Lectura con buffer para mejorar el rendimiento

Para archivos grandes u operaciones de lectura frecuentes, se recomienda usar BufferedInputStream como envoltorio para mejorar el rendimiento.

Ejemplo

try (InputStream input = new BufferedInputStream(new FileInputStream("largefile.dat"))) {
    // Operación de lectura
} catch (IOException e) {
    e.printStackTrace();
}

Manejar correctamente las excepciones

Las operaciones IO pueden lanzar IOException, se deben manejar adecuadamente estas excepciones.


5. Preguntas frecuentes

¿Por qué el método read() devuelve int en lugar de byte?

Porque se necesita un valor especial (-1) para indicar el final del flujo, y el tipo byte no puede representar -1.

¿Cómo convertir InputStream a String?

Ejemplo

public static String convertToString(InputStream input) throws IOException {
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(input))) {
        StringBuilder stringBuilder = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            stringBuilder.append(line);
        }
        return stringBuilder.toString();
    }
}

¿Cómo copiar InputStream?

InputStream normalmente solo se puede leer una vez; si necesitas leerlo varias veces, puedes copiar su contenido a un array de bytes o a un ByteArrayInputStream.


6. Resumen

La clase InputStream es uno de los componentes centrales del sistema I/O de Java y proporciona la funcionalidad básica para leer datos de bytes. Comprender InputStream y sus subclases es fundamental para manejar diversas fuentes de entrada (como archivos, conexiones de red, búferes de memoria, etc.). En aplicaciones prácticas, se debe prestar atención a la gestión de recursos, el manejo de excepciones y la optimización del rendimiento.

Otras extensiones