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.
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 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 :-)
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 .
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.
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:
le tuyau est le flux
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 flux
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 .
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é.
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?
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.
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.
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.
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.
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