web-dev-qa-db-fra.com

Qu'est-ce qu'un flux?

Qu'est-ce qu'un flux dans le monde de la programmation? Pourquoi en avons-nous besoin?

Veuillez expliquer à l'aide d'une analogie, si possible.

110
pokrate

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:

  • lire un octet. La prochaine fois que vous lirez, vous obtiendrez l'octet suivant, et ainsi de suite.
  • lire plusieurs octets du flux dans un tableau
  • chercher (déplacer votre position actuelle dans le flux, de sorte que la prochaine fois que vous lirez, vous obtiendrez des octets de la nouvelle position)
  • écrire un octet
  • écrire plusieurs octets d'un tableau dans le flux
  • ignorer les octets du flux (c'est comme lire, mais vous ignorez les données. Ou si vous préférez, c'est comme chercher, mais ne peut que progresser.)
  • Repoussez les octets dans un flux d'entrée (c'est comme "annuler" pour la lecture - vous remettez quelques octets en arrière dans le flux, de sorte que la prochaine fois que vous lirez, c'est ce que vous verrez. Il est parfois utile pour les analyseurs, comme c'est le cas:
  • coup d'œil (regardez les octets sans les lire, afin qu'ils soient toujours là dans le flux pour être lus plus tard)

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 sont pas 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 qui contient 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, alors le flux Push back lit à partir du flux réel. Ceci est un exemple simple d'un "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 vraiment des tableaux, donc la recherche est simple) mais aussi des entrées/sorties de terminal (qui ne sont pas recherchables sauf si elles sont tamponnées), des sockets, des ports série, etc. Vous pouvez donc écrire du code qui dit soit "Je veux des données, et je m'en fiche d'où elles viennent ou comment elles sont arrivées ici", ou "Je produirai des données, et c'est entièrement à mon interlocuteur de savoir ce qui lui arrivera". 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 peux penser est qu'un flux est un tapis roulant venant vers vous ou s'éloignant de vous (ou parfois les deux). Vous retirez des trucs d'un flux d'entrée, vous mettez des trucs sur un flux de sortie. Certains convoyeurs peuvent être considérés 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 l'endroit où vous souhaitez lire/écrire dans le flux que vous recherchez.

Comme le dit IRBMe, cependant, il vaut mieux penser à un flux en termes d'opérations qu'il offre (qui varient d'une implémentation à l'autre, mais qui 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 de flux, vous pouvez les considérer comme une boîte avec un convoyeur entrant et un convoyeur sortant, que vous vous connectez à d'autres flux, puis la boîte effectue une transformation sur les données (les compresser ou changer les sauts de ligne UNIX à ceux du 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 peut être lu de l'autre. Pensez aux trous de ver :-)

136
Steve Jessop

Un flux est déjà une métaphore, une analogie, il n'est donc pas vraiment nécessaire d'en fournir un autre. Vous pouvez le considérer essentiellement comme un tuyau avec un débit 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. Il s'agit essentiellement d'une abstraction courante qui est placée sur des éléments où il existe 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 de nombreuses 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 où la lecture et l'écriture dans le flux lit et écrit sur une connexion réseau établie sous-jacente. Les flux pour l'écriture uniquement sont généralement appelés flux de sortie, comme dans this Par exemple, et de la même manière, les flux qui sont en lecture seule sont appelés flux d'entrée, comme dans l'exemple this .

Un flux peut effectuer la transformation ou l'encodage des données (un SslStream dans .Net, par exemple, va consommer les données de négociation SSL et vous les cacher; Un TelnetStream peut vous cacher les négociations Telnet, mais donner accès aux données; A ZipOutputStream in Java vous permet d'écrire dans des fichiers dans une archive Zip sans avoir à vous soucier de l'intérieur du format de fichier Zip.

Une autre chose courante que vous pourriez trouver est des flux textuels qui vous permettent d'écrire des chaînes au lieu d'octets, ou certaines langues 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, que vous devez connaître.

Certains flux prennent également en charge l'accès aléatoire, comme dans l'exemple this . Un flux réseau, d'autre part, pour des raisons évidentes, ne le ferait pas.

Les systèmes d'exploitation de type UNIX prennent également en charge le modèle de flux avec l'entrée et la sortie du programme, comme décrit ici .

57
IRBMe

Les réponses données jusqu'à présent sont excellentes. Je n'en fournis qu'un autre pour souligner qu'un flux n'est pas une séquence d'octets ou spécifique à un langage de programmation car le concept est universel (alors que sa mise en œuvre peut être unique). Je vois souvent une abondance d'explications en ligne en termes de SQL, ou C ou Java, qui ont du sens car un flux de fichiers traite des emplacements de mémoire et des opérations de bas niveau. Mais ils expliquent 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.

La métaphore

Comme mentionné, un stream est une métaphore, une abstraction de quelque chose de plus complexe. Pour faire travailler votre imagination, je propose quelques autres métaphores:

  1. vous voulez remplir une piscine vide avec de l'eau. une façon d'y parvenir consiste à attacher un tuyau à un robinet, en plaçant l'extrémité du tuyau dans la piscine et en ouvrant l'eau.

le tuyau est le flux

  1. de même, si vous vouliez recharger votre voiture avec du gaz, vous iriez à une pompe à essence, insérez la buse dans votre réservoir de gaz et ouvrez la valve en serrant le levier de verrouillage.

le tuyau, la buse et les mécanismes associés pour permettre au gaz de s'écouler dans votre réservoir est le flux

  1. si vous devez vous rendre au travail, vous commencerez à conduire de votre domicile au bureau en utilisant l'autoroute.

l'autoroute est le flux

  1. si vous voulez avoir une conversation avec quelqu'un, vous utiliseriez vos oreilles pour entendre et votre bouche pour parler.

vos oreilles et vos yeux sont des ruisseaux

J'espère que vous remarquerez dans ces exemples que les métaphores de flux n'existent que pour permettre à quelque chose de le traverser (ou sur lui 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 s'il n'y a pas d'eau qui 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 qui peut traverser une autoroute.

Ainsi, un flux peut exister sans aucune donnée le traversant tant qu'il est connecté à un fichier .

Suppression de l'abstraction

Ensuite, nous devons répondre à quelques questions. Je vais utiliser des fichiers pour décrire les flux, alors ... Qu'est-ce qu'un fichier? Et comment lisons-nous un fichier? J'essaierai d'y répondre tout en conservant un certain niveau d'abstraction pour éviter une complexité inutile et utiliserai le concept de fichier relatif à un système d'exploitation Linux en raison de sa simplicité et de son accessibilité.

Qu'est-ce qu'un fichier?

Un fichier est une abstraction :)

Ou, aussi simplement que je peux l'expliquer, un fichier est une structure de données en une partie décrivant le fichier et une donnée en partie qui est le contenu réel.

La partie de structure de données (appelée un 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 du 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 dur 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 finalement y faire face. et oui, fichiers sont beaucoup plus complexes).

Jusqu'ici tout va bien. Mais comment obtenir le contenu du fichier, disons une lettre d'amour à ton beau, afin que nous puissions l'imprimer?

Lire un fichier

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? C'est très méthodiquement la réponse. 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 qu'il a un emplacement mémoire auquel se connecter ou 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, par exemple, un flux pour recevoir une entrée ou un flux pour envoyer le contenu d'un fichier à une sortie standard. UNIX/linux se connecte et maintient 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 en tant que structures de données elles-mêmes ou objets, 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 des erreurs du fichier auquel un flux est connecté. cin de C++ est un exemple d'objet stream.

Certes, si vous le souhaitez, vous pouvez écrire votre propre flux.

Définition

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.

7
rekurzion

En plus des éléments mentionnés ci-dessus, il existe différents types de flux - tels que définis dans les langages de programmation fonctionnels tels que Scheme ou Haskell - une infrastructure de données éventuellement infinie qui est générée par une fonction à la demande.

6
EFraim

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 un file d'attente sans stocker la persistance.

Avons-nous donc besoin de files d'attente? Tu décides.

5
Marcus

Le mot "flux" a été choisi parce qu'il représente (dans la vie réelle) une signification très similaire à ce que nous voulons transmettre lorsque nous l'utilisons.

Commencez à penser à l'analogie avec un jet d'eau. Vous recevez un flux continu de données, tout comme l'eau coule en continu dans une rivière. Vous ne savez pas nécessairement d'où viennent 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 d'importance. Ceci est très similaire à la réception d'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 d'importance. source

4
Premraj