Respuestas:
Una secuencia representa una secuencia de objetos (generalmente bytes, pero no necesariamente), a los que se puede acceder en orden secuencial. Operaciones típicas en una secuencia:
Una secuencia en particular puede admitir lectura (en cuyo caso es una "secuencia de entrada"), escritura ("secuencia de salida") o ambas. No todas las transmisiones son buscables.
El retroceso es bastante raro, pero siempre puede agregarlo a una secuencia envolviendo la secuencia de entrada real en otra secuencia de entrada que contiene un búfer interno. Las lecturas provienen del búfer, y si retrocede, los datos se colocan en el búfer. Si no hay nada en el búfer, la secuencia de retroceso se lee de la secuencia real. Este es un ejemplo simple de un "adaptador de flujo": se encuentra en el "extremo" de un flujo de entrada, es un flujo de entrada en sí mismo y hace algo adicional que el flujo original no hizo.
Stream es una abstracción útil porque puede describir archivos (que en realidad son matrices, por lo tanto, la búsqueda es sencilla) pero también la entrada / salida de terminal (que no se puede buscar a menos que esté almacenada), sockets, puertos serie, etc. Para que pueda escribir código que diga o "Quiero algunos datos, y no me importa de dónde provienen o cómo llegaron aquí", o "Produciré algunos datos, y depende de mi persona que llama lo que le sucede". El primero toma un parámetro de flujo de entrada, el segundo toma un parámetro de flujo de salida.
La mejor analogía que se me ocurre es que una corriente es una cinta transportadora que se dirige hacia usted o se aleja de usted (o, a veces, ambas). Sacas cosas de un flujo de entrada, pones cosas en un flujo de salida. Algunos transportadores se pueden considerar como que salen de un agujero en la pared; no son buscables, leer o escribir es un trato único. Algunos transportadores se colocan frente a usted, y usted puede moverse eligiendo el paradero en la secuencia que desea leer / escribir, eso es lo que busca.
Sin embargo, como dice IRBMe, es mejor pensar en una secuencia en términos de las operaciones que ofrece (que varían de implementación en implementación, pero tienen mucho en común) en lugar de una analogía física. Las transmisiones son "cosas que puedes leer o escribir". Cuando comience a conectar adaptadores de flujo, puede pensar en ellos como una caja con un transportador dentro y un transportador fuera, que se conecta a otros flujos y luego el cuadro realiza alguna transformación en los datos (comprimirlos o cambiar los avances de línea UNIX) a DOS, o lo que sea). Las tuberías son otra prueba exhaustiva de la metáfora: ahí es donde creas un par de transmisiones de modo que todo lo que escribes en una se pueda leer de la otra. Piensa en los agujeros de gusano :-)
Una transmisión ya es una metáfora, una analogía, por lo que realmente no hay necesidad de proporcionar otra. Se puede considerar básicamente como una tubería con un flujo de agua en el que el agua es en realidad datos y la tubería es la corriente. Supongo que es una especie de tubería de 2 vías si la corriente es bidireccional. Básicamente es una abstracción común que se coloca sobre cosas donde hay un flujo o secuencia de datos en una o ambas direcciones.
En lenguajes como C #, VB.Net, C ++, Java, etc., la metáfora de flujo se usa para muchas cosas. Hay secuencias de archivos, en las que abre un archivo y puede leer desde la secuencia o escribir en ella continuamente; Hay flujos de red en los que leer y escribir en el flujo lee y escribe en una conexión de red establecida subyacente. Las secuencias para escribir solo se denominan secuencias de salida, como en este ejemplo, y de manera similar, las secuencias que son solo para lectura se denominan secuencias de entrada, como en este ejemplo.
Un flujo puede realizar la transformación o la codificación de datos (un SslStream en .Net, por ejemplo, se comerá los datos de negociación SSL y se los ocultará; un TelnetStream podría ocultarle las negociaciones de Telnet, pero le proporcionará acceso a los datos; A ZipOutputStream en Java le permite escribir en archivos en un archivo zip sin tener que preocuparse por las partes internas del formato de archivo zip.
Otra cosa común que puede encontrar son las secuencias de texto que le permiten escribir cadenas en lugar de bytes, o algunos idiomas proporcionan secuencias binarias que le permiten escribir tipos primitivos. Una cosa común que encontrará en las secuencias de texto es una codificación de caracteres, que debe tener en cuenta.
Algunas transmisiones también admiten acceso aleatorio, como en este ejemplo. Una transmisión de red, por otro lado, por razones obvias, no lo haría.
Los sistemas operativos similares a UNIX también admiten el modelo de flujo con entrada y salida del programa, como se describe aquí .
Las respuestas dadas hasta ahora son excelentes. Solo proporciono otro para resaltar que una secuencia no es una secuencia de bytes o específica de un lenguaje de programación ya que el concepto es universal (mientras que su implementación puede ser única). A menudo veo una gran cantidad de explicaciones en línea en términos de SQL, C o Java, que tienen sentido ya que un flujo de archivos trata con ubicaciones de memoria y operaciones de bajo nivel. Pero a menudo abordan cómo crear un flujo de archivos y operar en el archivo potencial en su idioma dado en lugar de discutir el concepto de flujo.
Como se mencionó, a stream
es una metáfora, una abstracción de algo más complejo. Para que tu imaginación funcione, ofrezco algunas otras metáforas:
la manguera es la corriente
la manguera, la boquilla y los mecanismos asociados para permitir que el gas fluya hacia su tanque es la corriente
la autopista es la corriente
tus oídos y ojos son corrientes
Esperemos que en estos ejemplos note que las metáforas de la corriente solo existen para permitir que algo viaje a través de ella (o en ella en el caso de la autopista) y no siempre plantean lo que están transfiriendo. Una distinción importante. No nos referimos a nuestros oídos como una secuencia de palabras. Una manguera sigue siendo una manguera si no fluye agua a través de ella, pero tenemos que conectarla a una espita para que haga su trabajo correctamente. Un automóvil no es el único 'tipo' de vehículo que puede atravesar una autopista.
Por lo tanto, puede existir una secuencia que no tenga datos viajando a través de ella siempre que esté conectada a un archivo .
A continuación, debemos responder algunas preguntas. Voy a usar archivos para describir transmisiones, así que ... ¿Qué es un archivo? ¿Y cómo leemos un archivo? Intentaré responder esto manteniendo un cierto nivel de abstracción para evitar una complejidad innecesaria y utilizaré el concepto de un archivo relativo a un sistema operativo Linux debido a su simplicidad y accesibilidad.
Un archivo es una abstracción :)
O, tan simple como puedo explicar, un archivo es una estructura de datos de una parte que describe el archivo y los datos de una parte que es el contenido real.
La parte de la estructura de datos (llamada inodo en sistemas UNIX / linux) identifica piezas importantes de información sobre el contenido, pero no incluye el contenido en sí (o un nombre del archivo). Una de las piezas de información que guarda es una dirección de memoria donde comienza el contenido. Entonces, con un nombre de archivo (o un enlace duro en Linux), un descriptor de archivo (un nombre de archivo numérico que le importa al sistema operativo) y una ubicación inicial en la memoria, tenemos algo que podemos llamar un archivo.
(la clave para llevar es un 'archivo' definido por el sistema operativo ya que es el sistema operativo el que finalmente tiene que lidiar con él. Y sí, los archivos son mucho más complejos).
Hasta aquí todo bien. Pero, ¿cómo podemos obtener el contenido del archivo, decir una carta de amor a su novio, para que podamos imprimirlo?
Si comenzamos desde el resultado y retrocedemos, cuando abrimos un archivo en nuestra computadora, todo su contenido se salpica en nuestra pantalla para que lo podamos leer. ¿Pero cómo? Muy metódicamente es la respuesta. El contenido del archivo en sí es otra estructura de datos. Supongamos una serie de caracteres. También podemos pensar en esto como una cadena.
Entonces, ¿cómo 'leemos' esta cadena? Al encontrar su ubicación en la memoria e iterar a través de nuestra matriz de caracteres, un carácter a la vez hasta llegar al final del carácter de archivo. En otras palabras, un programa.
Una secuencia se 'crea' cuando se llama a su programa y tiene una ubicación de memoria para conectarse o conectarse . Al igual que nuestro ejemplo de manguera de agua, la manguera es ineficaz si no está conectada a una espita. En el caso de la transmisión, debe estar conectada a un archivo para que exista.
Las secuencias se pueden refinar aún más, por ejemplo, una secuencia para recibir entrada o una secuencia para enviar el contenido de un archivo a la salida estándar. UNIX / linux conecta y mantiene abiertos 3 flujos de archivos para nosotros de inmediato, stdin (entrada estándar), stdout (salida estándar) y stderr (error estándar). Las secuencias se pueden construir como estructuras de datos en sí mismas u objetos, lo que nos permite realizar operaciones más complejas de la transmisión de datos a través de ellas, como abrir la secuencia, cerrar la secuencia o verificar el archivo al que está conectada una secuencia. C ++ cin
es un ejemplo de un objeto de flujo.
Seguramente, si así lo elige, puede escribir su propia transmisión.
Un flujo es una pieza de código reutilizable que abstrae la complejidad de tratar con datos mientras proporciona operaciones útiles para realizar en datos.
Otra analogía: no puede nadar contra una secuencia, es por eso que solo puede tomar el siguiente bit, byte, cadena u objeto de la secuencia, mientras se eliminan los datos ya leídos. Un boleto de ida ... o básicamente solo una cola sin almacenar persistencia.
Entonces, ¿necesitamos colas? Tú decides.
La palabra "transmisión" ha sido elegida porque representa (en la vida real) un significado muy similar a lo que queremos transmitir cuando la usamos.
Comienza a pensar en la analogía de una corriente de agua. Recibe un flujo continuo de datos, al igual que el agua fluye continuamente en un río. No necesariamente sabe de dónde provienen los datos, y la mayoría de las veces no es necesario; ya sea desde un archivo, un socket o cualquier otra fuente, realmente no debería (no debería) importar. Esto es muy similar a recibir una corriente de agua, por lo que no necesita saber de dónde viene; ya sea de un lago, una fuente o cualquier otra fuente, realmente no debería importar. fuente