¿Qué significan exactamente "Stream" y "Buffer" en Java I / O?

83

Acabo de aprender sobre el uso de entrada / salida BufferedReader.

Quería saber cuáles son exactamente los significados del término Streamy Buffer.

También para qué nos sirve esta línea de código:

BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
usuario122345656
fuente

Respuestas:

202

Java tiene dos tipos de clases para entrada y salida (E / S): flujos y lectores / escritores .

(Corrientes InputStream, OutputStreamy todo lo que se extiende estos) son para la lectura y escritura de datos binarios de los archivos, la red, o cualquier otro dispositivo.

Los lectores y escritores son para leer y escribir texto (caracteres). Son una capa encima de los flujos, que convierte datos binarios (bytes) en caracteres y viceversa, utilizando una codificación de caracteres .

Leer datos del disco byte a byte es muy ineficaz. Una forma de acelerarlo es usar un búfer: en lugar de leer un byte a la vez, lee algunos miles de bytes a la vez y los coloca en un búfer, en la memoria. Luego puede mirar los bytes en el búfer uno por uno.

El tutorial de Java de Oracle sobre E / S lo explica en detalle.

Mirando la línea de código que proporcionó:

BufferedReader br=new BufferedReader(new InputStreamReader(System.in));

System.ines un InputStream. Creas un InputStreamReaderque lee bytes desde System.in. Luego envuelve eso en un BufferedReader.

Entonces, al final, tienes un BufferedReaderque lee de un InputStreamReaderque lee System.in.

Jesper
fuente
1
Gracias por tu respuesta, pero tengo una confusión Como dijiste, leemos algunos miles de bytes a la vez y los colocamos en el búfer; entonces, ¿esto significa que el búfer es solo un lugar en la memoria donde estamos almacenando cosas?
user122345656
3
@Jespe. Dijiste "Una forma de acelerarlo es usar un búfer: en lugar de leer un byte a la vez, lees unos pocos miles de bytes a la vez y los colocas en un búfer, en la memoria. Luego puedes mirar los bytes en el búfer uno por uno ". Sí, es cierto, pero creo que con el búfer también, se lee un solo byte a la vez.La única diferencia es que creo que se coloca en el búfer y el programa lo lee desde el búfer en lugar del disco
M Sach
7
@ user122345656 Sí, un búfer es un lugar en la memoria para almacenar datos temporalmente.
Jesper
14
@MSach Piense en lo que sucede cuando desea leer datos de un disco duro. Para leer un byte en una ubicación determinada, debe esperar hasta que el disco haya girado hasta que la cabeza esté por encima de la ubicación en el disco donde está el byte a leer. Si hubiera leído solo 1 byte en ese momento y el siguiente byte después, tendría que esperar hasta que el disco haya realizado una rotación completa para leer el siguiente byte. Es mucho más eficiente leer un bloque de bytes consecutivos.
Jesper
2
@parsecer Streams son para leer bytes; los lectores son para leer texto (caracteres). InputStreamReaderes un envoltorio alrededor de un InputStreamque le permite leer texto de un InputStream. Si solo desea leer bytes (no caracteres), no es necesario InputStreamReader. Es útil si desea interpretar los bytes como caracteres de texto.
Jesper
19

Buffer:

Es una región de un almacenamiento de memoria física que se utiliza para almacenar datos temporalmente mientras se mueven de un lugar a otro. Ese almacenamiento de memoria física sería RAM (memoria de acceso aleatorio) en la mayoría de los casos.

Pero desde el contexto de esta pregunta, Buffer se usa al leer / escribir datos. No es necesario utilizarlo al mover datos de un lugar a otro.

Ejemplo de búfer: si su sistema tiene 4 GB de RAM, el sistema podría asignar 4 KB de memoria (RAM) para búfer . KB - Kilobyte (s), GB - Gigabyte (s)

Secuencia de E / S (o) Secuencia:

I / O Stream representa una fuente de entrada o un destino de salida. Una secuencia puede representar muchos tipos diferentes de fuentes y destinos, incluidos archivos de disco, dispositivos, otros programas y matrices de memoria.

E / S significa Entrada / Salida.

Por lo tanto, Input Stream puede ser una fuente de entrada como un archivo de disco, una conexión de red, etc.

Y Output Stream puede ser un destino de salida como un archivo de disco, una conexión de red, etc.

Según la documentación oficial de JAVA , los Streams son de 3 tipos.

  1. Flujos de bytes (leer o escribir bytes)
  2. Flujos de caracteres (leer o escribir caracteres)
  3. Flujos almacenados en búfer (leer o escribir en búfer para mayor eficiencia)

Secuencias de bytes:

Realizan entrada y salida de bytes de 8 bits. Todas las clases de flujo de bytes descienden de InputStream y OutputStream .

Las clases de flujo de entrada de bytes obtienen la entrada como bytes sin procesar . Las clases de flujo de salida de bytes dan salida como bytes sin procesar .

InputStream- Subclases conocidas directas

AudioInputStream, ByteArrayInputStream, FileInputStream, FilterInputStream, InputStream, ObjectInputStream, PipedInputStream, SequenceInputStream, StringBufferInputStream.

OutputStream- Subclases conocidas directas

ByteArrayOutputStream, FileOutputStream, FilterOutputStream, ObjectOutputStream, OutputStream, PipedOutputStream

Flujos de caracteres: son una capa sobre los flujos de bytes. Convierten bytes (datos binarios) en caracteres y caracteres en bytes, utilizando una codificación de caracteres.

Todas las clases de flujo de caracteres descienden de Reader y Writer .

Reader - Subclases conocidas directas

BufferedReader, CharArrayReader, FilterReader, InputStreamReader, PipedReader, StringReader

Writer - Subclases conocidas directas

BufferedWriter, CharArrayWriter, FilterWriter, OutputStreamWriter, PipedWriter, PrintWriter, StringWriter

Los flujos de bytes y los flujos de caracteres utilizan E / S sin búfer .

Esto significa que cada solicitud de lectura o escritura es manejada directamente por el sistema operativo subyacente. Esto puede hacer que un programa sea mucho menos eficiente, ya que cada una de estas solicitudes a menudo desencadena el acceso al disco, la actividad de la red o alguna otra operación que es relativamente costosa. Para reducir este tipo de sobrecarga, la plataforma Java implementa flujos de E / S en búfer.

Secuencias almacenadas en búfer:

Los flujos de entrada almacenados en búfer leen datos de un área de memoria conocida como búfer ; la API de entrada nativa se llama solo cuando el búfer está vacío.

De manera similar, los flujos de salida almacenados en búfer escriben datos en un búfer y la API de salida nativa se llama solo cuando el búfer está lleno.

Un programa puede convertir una secuencia sin búfer en una secuencia con búfer usando el lenguaje de envoltura, donde el objeto de la secuencia sin búfer se pasa al constructor para una clase de secuencia con búfer .

Ejemplo:

inputStream = new BufferedReader(new FileReader("xanadu.txt"));
outputStream = new BufferedWriter(new FileWriter("characteroutput.txt"));

Hay 4 clases de secuencias almacenadas en búfer que se utilizan para envolver secuencias sin búfer:

Para crear secuencias de bytes almacenadas en búfer , utilice BufferedInputStreamy BufferedOutputStreamclases.

Para crear flujos de caracteres en búfer , utilice y clases.BufferedReaderBufferedWriter

AnV
fuente
1
Estaba buscando una explicación tan profunda para java io. Muchas gracias.
Arif Reza
14

Bueno, es una pregunta en la mente de todos los que comienzan a trabajar en el paquete java.io. Para responder a sus preguntas, los términos InputStreamReader y BufferedReader representan solo los objetos java (no hay nada especial en ellos), pero se crean para operaciones io como leer y escribir desde / hacia diferentes entradas / salidas como archivo, objeto, etc.

Ahora vamos a la fila

BufferedReader br=new BufferedReader(new InputStreamReader(System.in));

InputStreamReader es la clase para leer el flujo de entrada de bytes, pero leer cada byte es una operación costosa, por lo que lo estamos envolviendo en BufferedReader para almacenarlo en búfer (que es el patrón del decorador)

Entonces, lo que sucederá es que incluso antes de comenzar a leer, bufferReader almacenará una parte de los bytes en el registro y cuando realice la operación de lectura. se leerá desde esa ubicación, que es mucho menos costosa que leer desde la consola / archivo. Pero en el caso de InputStreamReader, cuando realiza la operación de lectura cada vez que se realiza la operación de acceso al disco

M Sach
fuente
+1, pero preferiría si hubiera agregado enlaces de referencia para el decorador de información y cada vez que se realiza una operación de acceso al disco
shareef
Ese último párrafo resume bien los beneficios. Gracias por eso.
Dave Voyles
3

Un flujo es la conexión y la información real que se pasa entre puntos. El búfer es un contenedor de almacenamiento que almacena parte o la totalidad de los datos transmitidos y los alimenta al dispositivo de salida.

Por supuesto, el punto es que si la transmisión se ralentiza más allá de la velocidad de datos requerida para mostrar los datos, la salida se detendrá. El búfer evita esto.

PGallagher
fuente
Gracias por ans. Pero una pregunta que me vino a la mente es ¿qué quieres decir con datos transmitidos? Por favor, elabora esto.
user122345656
1
Lo siento por la respuesta tardía. Si imagina un ejemplo simple de un archivo de 10Mb en el servidor. El servidor tiene el archivo completo, pero no puede enviar el archivo completo en un paquete. En cambio, el archivo se divide en un número finito de bloques. Luego, cada bloque se envía a la computadora remota y se vuelve a ensamblar. Para la transmisión de datos en vivo, se aplica la misma teoría. Pero el servidor toma los datos en vivo y los envía como streampaquetes. Luego, la computadora remota almacena cada paquete en un búfer. La computadora remota lee los datos de su búfer y crea, digamos, un video de esto. ¡Espero que esto ayude!
PGallagher
1

Un búfer es una parte de la memoria que se utiliza para almacenar un flujo de datos de dispositivos periféricos. Luego, desde este búfer, este flujo de datos se recopila y almacena en variables. Una secuencia se puede definir como un flujo continuo de datos.

El mismo término "entrada / salida" no significa más que mover datos dentro y fuera de los búferes. Solo ten esto en tu mente todo el tiempo. Los procesos realizan E / S solicitando al sistema operativo que los datos se vacíen de un búfer (operación de escritura) o que se llene un búfer con datos (operación de lectura).
Diagrama lógico de cómo se mueven los datos

En términos simples, imagine que cuando escribe datos en un teclado, los datos se mueven a través de una tubería (el flujo ) al búfer y luego del búfer al disco (operación de escritura). De manera similar, cuando los datos se mueven del disco al búfer y del búfer a su consola, entonces es operación de lectura.

Puede leer los enlaces para una mejor comprensión. ¡Espero eso ayude!.
¿Qué es el búfer en Java?
Ingrese la descripción del enlace aquí

Kushagra
fuente