Qu'est-ce qu'un flux?


Réponses:


161

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éplacez votre position actuelle dans le flux, de sorte que la prochaine fois que vous lisez, vous obtenez des octets de la nouvelle position)
  • écrire un octet
  • écrire plusieurs octets d'un tableau dans le flux
  • sauter 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 aller que vers l'avant.)
  • repousser des 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 lisez c'est ce que vous verrez. C'est parfois utile pour les analyseurs, comme c'est le cas:
  • coup d'oeil (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 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 :-)


3
De loin la meilleure explication que j'ai lue. Couplé à ce qu'il dit dans SICP ("Le traitement de flux nous permet de modéliser des systèmes qui ont un état sans jamais utiliser d'affectation ou de données mutables."), Je pense que je comprends enfin. Je vous remercie!
Kyle Chadha

86

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.

  • MSDN donne un bon aperçu des flux dans .Net.
  • Sun a également un aperçu de leur classe générale OutputStream et InputStream .
  • En C ++, voici la documentation istream (flux d'entrée), ostream (flux de sortie) et iostream (flux bidirectionnel).

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 .


13

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.

La métaphore

Comme mentionné, a streamest une métaphore, une abstraction de quelque chose de plus complexe. Pour faire travailler votre imagination, j'offre d'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 ruisseau

  1. De même, si vous vouliez faire le plein d'essence dans votre voiture, vous iriez à une pompe à essence, insérez la buse dans votre réservoir d'essence et ouvrez la valve en appuyant sur 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 ruisseau

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

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 .

Supprimer l'abstraction

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é.

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 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?

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? 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 ++ cinest un exemple d 'objet de flux.

Si vous le souhaitez, vous pouvez sûrement é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.


Un flux est donc le support par lequel les données circulent. Il doit être connecté à la source des données et peut effectuer des opérations sur lui-même et sur les données qui le traversent.
KingBryan

Oui. ma seule raison d'écrire une réponse supplémentaire était de préciser qu'un flux peut exister même si les données ne le traversent pas. alors qu'un flux IRL (avec de l'eau et autres) cesse d'être un flux lorsque l'eau cesse de couler et peut prêter à confusion lorsqu'on pense à l'analogie.
rekurzion

1
J'apprends actuellement Java, et votre réponse m'a aidé à comprendre.
KingBryan

6

En plus des choses mentionnées ci-dessus, il existe un type différent de flux - tel que défini dans les langages de programmation fonctionnels tels que Scheme ou Haskell - une structure de données éventuellement infinie qui est générée par une fonction à la demande.


6

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.


cela signifie que dans un flux, vous devez avancer ne peut pas reculer. De plus, les données précédentes supprimées au fur et à mesure que vous
avancez,

5

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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.