Risposte:
Un flusso rappresenta una sequenza di oggetti (in genere byte, ma non necessariamente), a cui è possibile accedere in ordine sequenziale. Operazioni tipiche su uno stream:
Un flusso particolare potrebbe supportare la lettura (nel qual caso si tratta di un "flusso di input"), la scrittura ("flusso di output") o entrambi. Non tutti i flussi sono ricercabili.
Il push back è abbastanza raro, ma è sempre possibile aggiungerlo a uno stream avvolgendo il flusso di input reale in un altro flusso di input che contiene un buffer interno. Le letture provengono dal buffer e, se si esegue il push back, i dati vengono inseriti nel buffer. Se non c'è nulla nel buffer, il flusso push back legge dal flusso reale. Questo è un semplice esempio di "adattatore di flusso": si trova all'estremità di un flusso di input, è un flusso di input stesso e fa qualcosa in più rispetto al flusso originale.
Lo stream è un'astrazione utile perché può descrivere file (che sono realmente array, quindi la ricerca è semplice) ma anche input / output del terminale (che non è ricercabile a meno che non sia bufferizzato), socket, porte seriali, ecc. Quindi puoi scrivere codice che dice o "Voglio alcuni dati e non mi interessa da dove vengono o come sono arrivati qui", o "Produrrò alcuni dati, e dipende interamente dal mio chiamante cosa succede". Il primo accetta un parametro del flusso di input, il secondo accetta un parametro del flusso di output.
La migliore analogia a cui riesco a pensare è che un flusso è un nastro trasportatore che viene verso di te o ti allontana (o talvolta entrambi). Prendi le cose da un flusso di input, metti cose in un flusso di output. Alcuni nastri trasportatori che puoi immaginare escano da un buco nel muro: non sono ricercabili, leggere o scrivere è un affare solo una volta. Alcuni nastri trasportatori sono disposti di fronte a te e puoi spostarti scegliendo la posizione nello stream che vuoi leggere / scrivere - che sta cercando.
Come dice IRBMe, tuttavia, è meglio pensare a un flusso in termini di operazioni che offre (che variano da implementazione a implementazione, ma hanno molto in comune) piuttosto che per analogia fisica. Gli stream sono "cose che puoi leggere o scrivere". Quando si avvia la connessione degli adattatori di flusso, è possibile considerarli come una scatola con un convogliatore in entrata e un convogliatore in uscita, che si connette ad altri flussi e quindi la scatola esegue una trasformazione dei dati (zippandola o modificando gli avanzamenti di riga UNIX a quelli DOS o altro). Le pipe sono un altro test approfondito della metafora: è lì che crei una coppia di flussi in modo tale che qualsiasi cosa tu scriva in una possa essere letta dall'altra. Pensa ai wormhole :-)
Uno stream è già una metafora, un'analogia, quindi non c'è davvero bisogno di anticiparne un altro. Puoi pensarlo fondamentalmente come un tubo con un flusso di acqua in cui l'acqua è in realtà dati e il tubo è il flusso. Suppongo che sia una specie di tubo a 2 vie se il flusso è bidirezionale. È fondamentalmente un'astrazione comune che viene posta su cose in cui vi è un flusso o una sequenza di dati in una o entrambe le direzioni.
In linguaggi come C #, VB.Net, C ++, Java ecc., La metafora dello stream viene utilizzata per molte cose. Esistono flussi di file, in cui si apre un file e si può leggere dallo stream o scriverlo continuamente; Esistono flussi di rete in cui la lettura e la scrittura nel flusso legge e scrive su una connessione di rete stabilita sottostante. I flussi per la sola scrittura sono in genere chiamati flussi di output, come in questo esempio, e allo stesso modo, i flussi che sono di sola lettura sono chiamati flussi di input, come in questo esempio.
Un flusso può eseguire la trasformazione o la codifica dei dati (uno SslStream in .Net, ad esempio, divorerà i dati di negoziazione SSL e li nasconderà da te; un TelnetStream potrebbe nascondere le negoziazioni di Telnet da te, ma fornire l'accesso ai dati; A ZipOutputStream in Java consente di scrivere su file in un archivio zip senza doversi preoccupare degli interni del formato di file zip.
Un'altra cosa comune che potresti trovare sono flussi testuali che ti permettono di scrivere stringhe invece di byte, o alcune lingue forniscono flussi binari che ti permettono di scrivere tipi primitivi. Una cosa comune che troverai nei flussi testuali è una codifica dei caratteri, di cui dovresti essere consapevole.
Alcuni stream supportano anche l'accesso casuale, come in questo esempio. Un flusso di rete, d'altra parte, per ovvie ragioni, non lo farebbe.
Anche i sistemi operativi UNIX supportano il modello di flusso con input e output del programma, come descritto qui .
Le risposte fornite finora sono eccellenti. Ne sto fornendo un altro per evidenziare che uno stream non è una sequenza di byte o specifico di un linguaggio di programmazione poiché il concetto è universale (mentre la sua implementazione può essere unica). Vedo spesso molte spiegazioni online in termini di SQL, o C o Java, che hanno senso come un filestream si occupa di posizioni di memoria e operazioni di basso livello. Ma spesso affrontano come creare un filestream e operare sul file potenziale nella loro lingua, piuttosto che discutere il concetto di stream.
Come detto a stream
è una metafora, un'astrazione di qualcosa di più complesso. Per far funzionare la tua immaginazione offro alcune altre metafore:
il tubo è il flusso
il tubo flessibile, l'ugello e i meccanismi associati per consentire al gas di fluire nel serbatoio è il flusso
l'autostrada senza pedaggio è il flusso
le tue orecchie e i tuoi occhi sono flussi
Si spera che in questi esempi si noti che le metafore del flusso esistono solo per consentire a qualcosa di attraversarlo (o su di esso nel caso dell'autostrada senza pedaggio) e non si pongono sempre ciò che stanno trasferendo. Una distinzione importante. Non ci riferiamo alle nostre orecchie come una sequenza di parole. Un tubo è ancora un tubo se non vi scorre acqua, ma dobbiamo collegarlo a un rubinetto perché faccia correttamente il suo lavoro. Un'auto non è l'unico "tipo" di veicolo che può attraversare un'autostrada senza pedaggio.
Pertanto può esistere uno stream che non ha dati che lo attraversano finché è collegato a un file .
Successivamente, dobbiamo rispondere ad alcune domande. Userò i file per descrivere i flussi, quindi ... Cos'è un file? E come leggiamo un file? Cercherò di rispondere a questo mantenendo un certo livello di astrazione per evitare complessità non necessarie e userò il concetto di un file relativo a un sistema operativo Linux per la sua semplicità e accessibilità.
Un file è un'astrazione :)
Oppure, per quanto posso spiegare, un file è una struttura di dati di una parte che descrive il file e una parte di dati che è il contenuto effettivo.
La parte della struttura dei dati (chiamata inode nei sistemi UNIX / linux) identifica importanti informazioni sul contenuto, ma non include il contenuto stesso (o un nome del file per quella materia). Una delle informazioni che conserva è un indirizzo di memoria a cui inizia il contenuto. Quindi con un nome di file (o un hard link in linux), un descrittore di file (un nome di file numerico a cui tiene il sistema operativo) e una posizione iniziale in memoria abbiamo qualcosa che possiamo chiamare un file.
(la chiave da asporto è un 'file' definito dal sistema operativo in quanto è il sistema operativo che alla fine deve occuparsene. E sì, i file sono molto più complessi).
Fin qui tutto bene. Ma come possiamo ottenere il contenuto del file, dire una lettera d'amore al tuo fidanzato, così possiamo stamparlo?
Se partiamo dal risultato e ci spostiamo all'indietro, quando apriamo un file sul nostro computer, l'intero contenuto viene schizzato sullo schermo per consentirci di leggere. Ma come? Molto metodicamente è la risposta. Il contenuto del file stesso è un'altra struttura di dati. Supponiamo una matrice di personaggi. Possiamo anche pensare a questo come a una stringa.
Quindi, come possiamo "leggere" questa stringa? Trovando la sua posizione nella memoria e ripetendo la nostra gamma di caratteri, un carattere alla volta fino a raggiungere la fine del carattere del file. In altre parole, un programma.
Uno stream viene "creato" quando viene chiamato il suo programma e ha una posizione di memoria a cui collegarsi o connettersi . Proprio come il nostro esempio di tubo dell'acqua, il tubo è inefficace se non è collegato a un rubinetto. Nel caso del flusso, deve essere collegato a un file per esistere.
Gli stream possono essere ulteriormente perfezionati, ad esempio uno stream per ricevere input o uno stream per inviare i contenuti di un file all'output standard. UNIX / linux si connette e mantiene aperti 3 filestream per noi subito, bat, stdin (input standard), stdout (output standard) e stderr (errore standard). I flussi possono essere creati come strutture di dati stesse o oggetti che ci consentono di eseguire operazioni più complesse del flusso di dati attraverso di essi, come l'apertura del flusso, la chiusura del flusso o l'errore nel controllo del file a cui è collegato un flusso. C ++ cin
è un esempio di un oggetto stream.
Sicuramente, se lo desideri, puoi scrivere il tuo stream.
Un flusso è un pezzo di codice riutilizzabile che riassume la complessità della gestione dei dati e allo stesso tempo fornisce operazioni utili da eseguire sui dati.
Un'altra analogia: non puoi nuotare contro uno stream, ecco perché puoi semplicemente prendere il bit, il byte, la stringa o l'oggetto successivi dallo stream, mentre i dati già letti vengono eliminati. Un biglietto di sola andata ... o sostanzialmente solo una coda senza memorizzare persistenza.
Quindi abbiamo bisogno di code? Tu decidi.
La parola "flusso" è stata scelta perché rappresenta (nella vita reale) un significato molto simile a ciò che vogliamo trasmettere quando lo usiamo.
Inizia a pensare all'analogia con un flusso d'acqua. Ricevi un flusso continuo di dati, proprio come l'acqua scorre continuamente in un fiume. Non necessariamente sai da dove provengono i dati e molto spesso non è necessario; che si tratti di un file, di un socket o di qualsiasi altra fonte, non ha (non dovrebbe) importare davvero. Questo è molto simile alla ricezione di un flusso d'acqua, per cui non è necessario sapere da dove provenga; che si tratti di un lago, una fontana o qualsiasi altra fonte, non ha (non dovrebbe) importare davvero. fonte