Réponses:
Un flux représente une séquence d'objets (généralement des octets, mais pas nécessairement), auxquels on peut accéder dans un ordre séquentiel. Opérations typiques sur un flux:
Un flux particulier peut prendre en charge la lecture (auquel cas il s'agit d'un "flux d'entrée"), l'écriture ("flux de sortie") ou les deux. Tous les flux ne peuvent pas être recherchés.
Le refoulement est assez rare, mais vous pouvez toujours l'ajouter à un flux en enveloppant le flux d'entrée réel dans un autre flux d'entrée contenant un tampon interne. Les lectures proviennent du tampon, et si vous repoussez, les données sont placées dans le tampon. S'il n'y a rien dans le tampon, le flux de refoulement est lu à partir du flux réel. Ceci est un exemple simple d '"adaptateur de flux": il se trouve à la "fin" d'un flux d'entrée, c'est un flux d'entrée lui-même, et il fait quelque chose de plus que le flux d'origine n'a pas fait.
Stream est une abstraction utile car il peut décrire des fichiers (qui sont en réalité des tableaux, donc la recherche est simple) mais aussi des entrées / sorties de terminaux (qui ne sont pas recherchées sauf en mémoire tampon), des sockets, des ports série, etc. Vous pouvez donc écrire du code qui dit soit "Je veux des données, et je me fiche d'où elles viennent ou comment elles sont arrivées ici", ou "Je vais produire des données, et c'est entièrement à mon appelant ce qui leur arrive". Le premier prend un paramètre de flux d'entrée, le second prend un paramètre de flux de sortie.
La meilleure analogie à laquelle je puisse penser est qu'un ruisseau est une bande transporteuse venant vers vous ou s'éloignant de vous (ou parfois les deux). Vous enlevez des choses d'un flux d'entrée, vous mettez des choses sur un flux de sortie. Certains convoyeurs que vous pouvez considérer comme sortant d'un trou dans le mur - ils ne sont pas recherchés, la lecture ou l'écriture est une affaire unique. Certains convoyeurs sont disposés devant vous et vous pouvez vous déplacer en choisissant les allées et venues dans le flux que vous souhaitez lire / écrire - c'est la recherche.
Comme le dit IRBMe, cependant, il est préférable de penser à un flux en termes d'opérations qu'il offre (qui varient d'une implémentation à l'autre, mais ont beaucoup en commun) plutôt que par une analogie physique. Les flux sont des «choses que vous pouvez lire ou écrire». Lorsque vous commencez à connecter des adaptateurs en amont, vous pouvez les considérer comme une boîte avec un convoyeur d'entrée et un convoyeur de sortie, que vous connectez à d'autres flux, puis la boîte effectue une transformation sur les données (en les compressant ou en modifiant les sauts de ligne UNIX. aux DOS, ou autre). Les tuyaux sont un autre test approfondi de la métaphore: c'est là que vous créez une paire de flux de sorte que tout ce que vous écrivez dans l'un puisse être lu dans l'autre. Pensez aux trous de ver :-)
Un flux est déjà une métaphore, une analogie, il n'est donc vraiment pas nécessaire d'en proposer un autre. Vous pouvez le considérer essentiellement comme un tuyau avec un écoulement d'eau dans lequel l'eau est en fait des données et le tuyau est le ruisseau. Je suppose que c'est une sorte de tuyau à 2 voies si le flux est bidirectionnel. C'est fondamentalement une abstraction commune qui est placée sur des choses où il y a un flux ou une séquence de données dans une ou les deux directions.
Dans des langages tels que C #, VB.Net, C ++, Java, etc., la métaphore du flux est utilisée pour beaucoup de choses. Il existe des flux de fichiers dans lesquels vous ouvrez un fichier et pouvez lire à partir du flux ou y écrire en continu; Il existe des flux réseau dans lesquels la lecture et l'écriture dans le flux permettent de lire et d'écrire sur une connexion réseau établie sous-jacente. Les flux destinés à l'écriture uniquement sont généralement appelés flux de sortie, comme dans cet exemple, et de même, les flux destinés à la lecture uniquement sont appelés flux d'entrée, comme dans cet exemple.
Un flux peut effectuer la transformation ou le codage des données (un SslStream dans .Net, par exemple, va manger les données de négociation SSL et vous les cacher; Un TelnetStream peut vous cacher les négociations Telnet, mais vous donner accès aux données; A ZipOutputStream en Java vous permet d'écrire dans des fichiers dans une archive zip sans avoir à vous soucier des éléments internes du format de fichier zip.
Une autre chose courante que vous pourriez trouver est les flux textuels qui vous permettent d'écrire des chaînes au lieu d'octets, ou certains langages fournissent des flux binaires qui vous permettent d'écrire des types primitifs. Une chose courante que vous trouverez dans les flux textuels est un encodage de caractères, dont vous devez être conscient.
Certains flux prennent également en charge l'accès aléatoire, comme dans cet exemple. Un flux réseau, en revanche, pour des raisons évidentes, ne le ferait pas.
UNIX comme les systèmes d'exploitation prennent également en charge le modèle de flux avec entrée et sortie de programme, comme décrit ici .
Les réponses données jusqu'à présent sont excellentes. Je n'en fournit qu'un autre pour souligner qu'un flux n'est pas une séquence d'octets ou spécifique à un langage de programmation puisque le concept est universel (alors que son implémentation peut être unique). Je vois souvent une abondance d'explications en ligne en termes de SQL, C ou Java, ce qui a du sens car un flux de fichiers traite des emplacements mémoire et des opérations de bas niveau. Mais ils abordent souvent comment créer un flux de fichiers et opérer sur le fichier potentiel dans leur langue donnée plutôt que de discuter du concept de flux.
Comme mentionné, a stream
est une métaphore, une abstraction de quelque chose de plus complexe. Pour faire travailler votre imagination, j'offre d'autres métaphores:
le tuyau est le ruisseau
le tuyau, la buse et les mécanismes associés pour permettre au gaz de s'écouler dans votre réservoir est le flux
l'autoroute est le ruisseau
tes oreilles et tes yeux sont des ruisseaux
Espérons que vous remarquerez dans ces exemples que les métaphores de flux n'existent que pour permettre à quelque chose de voyager à travers lui (ou dessus dans le cas de l'autoroute) et ne posent pas toujours elles-mêmes la chose qu'elles transfèrent. Une distinction importante. Nous ne nous référons pas à nos oreilles comme une séquence de mots. Un tuyau est toujours un tuyau si aucune eau ne le traverse, mais nous devons le connecter à un robinet pour qu'il fasse correctement son travail. Une voiture n'est pas le seul «type» de véhicule à pouvoir traverser une autoroute.
Ainsi, un flux peut exister sans données qui le traversent tant qu'il est connecté à un fichier .
Ensuite, nous devons répondre à quelques questions. Je vais utiliser des fichiers pour décrire les flux donc ... Qu'est-ce qu'un fichier? Et comment lit-on un fichier? J'essaierai d'y répondre tout en conservant un certain niveau d'abstraction pour éviter une complexité inutile et j'utiliserai le concept de fichier relatif à un système d'exploitation Linux en raison de sa simplicité et de son accessibilité.
Un fichier est une abstraction :)
Ou, aussi simplement que je peux l'expliquer, un fichier est une structure de données d'une partie décrivant le fichier et une partie de données qui est le contenu réel.
La partie structure de données (appelée inode dans les systèmes UNIX / linux) identifie des informations importantes sur le contenu, mais n'inclut pas le contenu lui-même (ou un nom de fichier d'ailleurs). L'une des informations qu'il conserve est une adresse mémoire à l'endroit où le contenu commence. Donc, avec un nom de fichier (ou un lien physique sous Linux), un descripteur de fichier (un nom de fichier numérique qui intéresse le système d'exploitation) et un emplacement de départ en mémoire, nous avons quelque chose que nous pouvons appeler un fichier.
(la clé à retenir est qu'un «fichier» est défini par le système d'exploitation car c'est le système d'exploitation qui doit en fin de compte le gérer. Et oui, les fichiers sont beaucoup plus complexes).
Jusqu'ici tout va bien. Mais comment obtenir le contenu du fichier, dire une lettre d'amour à votre beau, pour que nous puissions l'imprimer?
Si nous partons du résultat et reculons, lorsque nous ouvrons un fichier sur notre ordinateur, tout son contenu est éclaboussé sur notre écran pour que nous puissions le lire. Mais comment? La réponse est très méthodique. Le contenu du fichier lui-même est une autre structure de données. Supposons un tableau de caractères. Nous pouvons également considérer cela comme une chaîne.
Alors, comment pouvons-nous «lire» cette chaîne? En trouvant son emplacement en mémoire et en parcourant notre tableau de caractères, un caractère à la fois jusqu'à atteindre un caractère de fin de fichier. En d'autres termes, un programme.
Un flux est «créé» lorsque son programme est appelé et il dispose d'un emplacement mémoire auquel s'attacher ou auquel se connecter . Tout comme notre exemple de tuyau d'eau, le tuyau est inefficace s'il n'est pas connecté à un robinet. Dans le cas du flux, il doit être connecté à un fichier pour qu'il existe.
Les flux peuvent être affinés davantage, par exemple, un flux pour recevoir une entrée ou un flux pour envoyer un contenu de fichiers vers une sortie standard. UNIX / linux se connecte et garde ouvert 3 flux de fichiers pour nous dès le départ, stdin (entrée standard), stdout (sortie standard) et stderr (erreur standard). Les flux peuvent être construits sous forme de structures de données ou d'objets eux-mêmes, ce qui nous permet d'effectuer des opérations plus complexes sur les données qui les traversent, comme l'ouverture du flux, la fermeture du flux ou la vérification d'erreur du fichier auquel un flux est connecté. C ++ cin
est un exemple d 'objet de flux.
Si vous le souhaitez, vous pouvez sûrement écrire votre propre flux.
Un flux est un morceau de code réutilisable qui résume la complexité du traitement des données tout en fournissant des opérations utiles à effectuer sur les données.
Une autre analogie: vous ne pouvez pas nager contre un flux, c'est pourquoi vous pouvez simplement prendre le bit, l'octet, la chaîne ou l'objet suivant du flux, tandis que les données déjà lues sont supprimées. Un aller simple ... ou simplement une file d'attente sans stockage de persistance.
Alors avons-nous besoin de files d'attente? Tu décides.
Le mot «flux» a été choisi car il représente (dans la vraie vie) un sens très similaire à ce que nous voulons transmettre lorsque nous l'utilisons.
Commencez à penser à l'analogie avec un courant d'eau. Vous recevez un flux continu de données, tout comme l'eau coule en permanence dans une rivière. Vous ne savez pas nécessairement d'où proviennent les données, et le plus souvent vous n'en avez pas besoin; que ce soit à partir d'un fichier, d'une socket ou de toute autre source, cela n'a pas (ne devrait pas) vraiment avoir d'importance. C'est très similaire à recevoir un jet d'eau, où vous n'avez pas besoin de savoir d'où il vient; que ce soit d'un lac, d'une fontaine ou de toute autre source, cela n'a pas (ne devrait pas) vraiment avoir d'importance. la source