2009-08-01 12 views
70

Che cos'è uno stream nel mondo di programmazione? Perchè ne abbiamo bisogno?Che cos'è uno stream?

Gentilmente spiegare con l'aiuto di un'analogia, se possibile.

+8

Questo è un duplicato di http://stackoverflow.com/questions/507747/can-you-explain-the-concept-of-streams. –

risposta

101

Un flusso rappresenta una sequenza di oggetti (in genere byte, ma non necessariamente), a cui è possibile accedere in ordine sequenziale. Operazioni tipiche su un flusso:

  • leggere un byte. La prossima volta che leggerete, otterrete il byte successivo, e così via.
  • letto diverse byte dal flusso in un array
  • cercano (spostare la posizione corrente nel flusso, in modo che la prossima volta che leggete si ottiene byte dalla nuova posizione)
  • scrittura di un byte
  • scrivere diversi byte da un array nel flusso
  • saltare byte dal flusso (questo è come leggere, ma si ignorano i dati. O se preferite E 'come cercare, ma può solo andare avanti.)
  • spinta byte di nuovo in un ingresso flusso (questo è come "annulla" per leggere - si spinge alcuni byte per il backup dello stream, in modo che la prossima volta si legga è quello che vedrai. E 'a volte utile per parser, come è:
  • peek (guarda byte senza leggerli, in modo che siano ancora lì nel flusso da leggere in seguito)

Un flusso particolare potrebbe supportare la lettura (in nel qual caso si tratta di un "flusso di input"), della scrittura ("flusso di output") o di entrambi. Non tutti i flussi sono ricercabili.

Il respingimento è 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 di pushback viene letto dal flusso reale. Questo è un semplice esempio di "stream adapter": si trova sulla "fine" di un flusso di input, è esso stesso un flusso di input e fa qualcosa in più che il flusso originale non ha.

Il flusso è un'astrazione utile perché può descrivere file (che sono in realtà matrici, quindi ricerca è semplice) ma anche terminale di input/output (che non è ricercabile a meno che non sia bufferizzato), socket, porte seriali, ecc. scrivi un codice che dice "Voglio alcuni dati, e non mi interessa da dove viene o come è arrivato qui", o "Produrrò alcuni dati, ed è interamente compito del mio interlocutore ciò che accade ad esso". 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 voi o che porta via da voi (o talvolta da entrambi). Prendi roba da un flusso di input, metti cose su un flusso di output. Alcuni trasportatori che si possono pensare come usciti da un buco nel muro - non sono cercabili, leggere o scrivere è un affare di una volta sola. Alcuni trasportatori sono disposti di fronte a te, e puoi muoverti scegliendo il luogo nel flusso che vuoi leggere/scrivere, quello che stai cercando.

Come dice IRBMe, tuttavia, è meglio pensare a un flusso in termini di operazioni che offre (che variano dall'implementazione all'implementazione, ma hanno molto in comune) piuttosto che da un'analogia fisica. Gli stream sono "cose ​​che puoi leggere o scrivere". Quando si avvia il collegamento degli adattatori del flusso, si può pensare di loro come una scatola con un trasportatore in, ed un convogliatore fuori, che si connette a altri flussi e quindi la casella esegue qualche trasformazione sui dati (zippare, o cambiando linefeeds UNIX a DOS, o qualsiasi altra cosa). I tubi sono un altro test approfondito della metafora: è lì che crei un paio di flussi in modo che tutto ciò che scrivi in ​​uno possa essere letto dall'altro. Pensa ai wormhole :-)

+1

Di gran lunga la migliore spiegazione che ho letto. Accoppiato con quello che dice in SICP ("L'elaborazione del flusso ci consente di modellare sistemi che hanno uno stato senza mai usare assegnazioni o dati mutabili."), Penso di averlo finalmente capito. Grazie! –

24

Un flusso è già una metafora, un'analogia, quindi non c'è davvero bisogno di farsene un altro. Si può pensare fondamentalmente come un tubo con un flusso d'acqua al suo interno in cui l'acqua è effettivamente dati e il tubo è il flusso. Suppongo che sia una specie di pipe a 2 vie se lo stream è bidirezionale. È fondamentalmente un'astrazione comune che viene posta su cose dove c'è un flusso o una sequenza di dati in una o entrambe le direzioni.

In lingue come C#, VB.Net, C++, Java ecc., La metafora del flusso viene utilizzata per molte cose. Ci sono flussi di file, in cui si apre un file e si può leggere dallo stream o scrivere ad esso; Esistono flussi di rete in cui la lettura e la scrittura nello stream vengono lette e scritte su una connessione di rete stabilita. Gli stream per la sola scrittura sono tipicamente chiamati flussi di output, come nell'esempio this e, analogamente, i flussi che sono di sola lettura sono chiamati flussi di input, come nell'esempio this.

Un flusso può eseguire la trasformazione o la codifica dei dati (uno SslStream in. Net, ad esempio, mangerà i dati di negoziazione SSL e lo nasconderà, Un TelnetStream potrebbe nascondere le negoziazioni Telnet da te, ma fornire l'accesso a i dati; A ZipOutputStream in Java consente di scrivere su file in un archivio zip senza doversi preoccupare degli interni del formato zip.

Un'altra cosa comune che si potrebbe trovare sono flussi testuali che consentono 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 a conoscenza.

Alcuni flussi supportano anche l'accesso casuale, come nell'esempio this. Un flusso di rete, d'altra parte, per ovvi motivi, non lo farebbe.

  • MSDN offre una buona panoramica dei flussi in. Netto.
  • Sun ha anche una panoramica della classe generale OutputStream e della classe InputStream.
  • In C++, ecco la documentazione di (flusso di input), ostream (flusso di output) e iostream (flusso bidirezionale).

I sistemi operativi UNIX simili supportano anche il modello di flusso con ingresso e uscita di programma, come descritto here.

5

In aggiunta alle cose sopra menzionate, c'è un diverso tipo di stream - come definito nei linguaggi di programmazione funzionale come Scheme o Haskell - una possibile infrastruttura infinita generata da una funzione su richiesta.

4

Un'altra analogia: Non è possibile nuotare contro una corrente, è per questo che si può solo prendere il bit successivo, byte, stringa o oggetto dal flusso, mentre i dati già letto viene eliminato. Un biglietto di sola andata...o fondamentalmente solo una coda senza memorizzare la persistenza.

Quindi abbiamo bisogno di code? Tu decidi.

+0

significa che in un flusso, devi andare avanti non può andare indietro. Inoltre i dati precedenti cancellati mentre vai avanti che salvano la memoria? –

3

La parola "flusso" è stata scelta perché rappresenta (nella vita reale) un significato molto simile a ciò che vogliamo trasmettere quando lo usiamo.

Iniziare a pensare all'analogia con un flusso d'acqua. Riceverai un flusso continuo di dati, proprio come l'acqua scorre continuamente in un fiume. Non si sa necessariamente da dove provengono i dati, e molto spesso non è necessario; sia da un file, da un socket o da qualsiasi altra fonte, non ha importanza (non dovrebbe). Questo è molto simile a ricevere un flusso d'acqua, per cui non è necessario sapere da dove proviene; sia da un lago, da una fontana o da qualsiasi altra fonte, non importa (non dovrebbe) importa davvero. source

Problemi correlati