2009-09-10 15 views
80

Gli stream sono un po 'misteriosi per me. Non so quando usare quale stream e come usarli. Qualcuno può spiegarmi come vengono utilizzati i flussi?C# utilizzando i flussi

Se ho capito bene, ci sono tre tipi di flusso:

  • stream
  • read stream
  • write stream

È corretto? E, ad esempio, qual è la differenza tra uno Memorystream e uno FileStream?

+11

Si consiglia di controllare http://stackoverflow.com/questions/507747/can-you-explain-the-concept-of-streams – Preets

+1

Prendere una matrice di byte e quindi creare un wrapper per esso ('Stream') che espone alcuni metodi utili come leggere, scrivere e cambiare posizione. Ora è possibile creare classi basate sul loro backing store (FileStream, MemoryStream) che ereditano da 'Stream' e si basano su tale funzionalità basata sul particolare backing store. –

risposta

47

A stream è un oggetto utilizzato per trasferire i dati. Esiste una classe stream generica System.IO.Stream, da cui derivano tutte le altre classi di flusso in .NET. La classe Stream si occupa di byte.

Le classi di flusso concreti vengono utilizzate per gestire altri tipi di dati rispetto ai byte.Per esempio:

  • La classe FileStream viene utilizzato quando la fonte esterna è un file
  • MemoryStream viene utilizzato per memorizzare i dati in memoria
  • System.Net.Sockets.NetworkStream gestisce i dati di rete

lettore/scrittore di flussi come come e StreamWriter non sono flussi - non sono derivati ​​da System.IO.Stream, sono progettati per aiutare a scrivere e leggere dati da e per lo streaming!

+3

Quindi, se ho capito bene, lo stream contiene i dati e non fa nulla con esso. Le classi 'helper' di lettura e scrittura possono gestire (manipolare) i dati all'interno del flusso? – Martijn

+6

No, Stream non è un contenitore di dati, viene utilizzato per trasferire dati, ad esempio FileStream trasferisce i dati dal byte [] al file fisico, NetworkStream trasferisce il byte [] dal socket. Le classi di Reader Writer sono classi helper da scrivere e leggere dallo stream, ad esempio StreamReader può essere utilizzato per leggere da Stream string not byte []. se assegnerai FileStream come parametro, leggerà da File, se NetworkStream dal socket. –

+0

Inoltre, StreamReader e StreamWriter sono per la lettura e la scrittura di flussi TEXT (caratteri). – 1c1cle

0

Nella maggior parte dei casi è possibile leggere e scrivere su uno stream, un memorandtream è una cosa che è possibile dichiarare per poter lavorare con i dati in memoria e un flusso di file è un flusso puntato a un file in scrivi o leggi da un file stream, quindi stai leggendo/scrivendo il file.

2

Vorrei iniziare con la lettura su stream su MSDN: http://msdn.microsoft.com/en-us/library/system.io.stream.aspx

MemoryStream e FileStream sono flussi utilizzati per lavorare con la memoria prime e dei file rispettivamente ...

+0

Grazie per il link. Mi è piaciuto "È possibile sfogliare il codice sorgente online, scaricare il riferimento per la visualizzazione offline e scorrere i sorgenti (comprese patch e aggiornamenti) durante il debug". Questa funzione offre un nuovo livello di conoscenza. – David

3

C'è solo un tipo di base di Stream . Tuttavia in varie circostanze alcuni membri lanciano un'eccezione quando vengono chiamati perché in quel contesto l'operazione non era disponibile.

Ad esempio un MemoryStream è semplicemente un modo per spostare i byte dentro e fuori da un blocco di memoria. Quindi puoi chiamare Leggi e scrivi su di esso.

D'altra parte uno FileStream consente di leggere o scrivere (o entrambi) da/a un file. Se puoi effettivamente leggere o scrivere dipende da come è stato aperto il file. Non puoi scrivere su un file se lo hai aperto solo per l'accesso in lettura.

1

Non chiamerei quei diversi tipi di flussi. La classe Stream ha proprietà CanRead e CanWrite che ti dicono se il particolare stream può essere letto e scritto.

La principale differenza tra diverse classi di stream (come MemoryStream vs FileStream) è il backing store - da cui i dati vengono letti o dove è stato scritto. È abbastanza ovvio dal nome. Un MemoryStream memorizza i dati solo in memoria, un FileStream è supportato da un file su disco, un NetworkStream legge i dati dalla rete e così via.

15

Gli stream sono utili per gestire grandi quantità di dati. Quando non è pratico caricare tutti i dati nella memoria contemporaneamente, è possibile aprirlo come flusso e lavorare con piccoli blocchi di esso.

+0

Mi piacerebbe vedere un esempio di quello che hai appena detto "lavorare con piccoli pezzi di esso". –

+2

Gli stream fanno bene anche a piccole quantità di dati. Se un programmatore C# vuole manipolare il contenuto di un file, deve utilizzare gli stream, indipendentemente dalla quantità di dati. La stessa affermazione vale anche per i network stream. Certo, se il programmatore sta codificando è un linguaggio di livello inferiore come C, allora è possibile scrivere caratteri o byte direttamente su un disco o su un socket, ma anche per una piccola quantità di dati, richiede molto tempo e è più soggetto a errore. – 1c1cle

40

Per espandere un po 'le altre risposte qui e aiutare a spiegare un sacco del codice di esempio che vedrai punteggiato, la maggior parte delle volte non leggi e scrivi direttamente in uno stream. Gli stream sono mezzi di basso livello per trasferire i dati.

Noterai che le funzioni di lettura e scrittura sono tutte orientate ai byte, ad es. WriteByte(). Non ci sono funzioni per gestire interi, stringhe, ecc. Ciò rende lo stream molto generico, ma meno semplice da utilizzare se, per esempio, si desidera semplicemente trasferire il testo.

Tuttavia, .NET fornisce classi che convertono tra tipi nativi e l'interfaccia di flusso di basso livello e trasferisce i dati ao dallo stream per te. Alcune di queste classi degne di nota sono:

StreamWriter // Badly named. Should be TextWriter. 
StreamReader // Badly named. Should be TextReader. 
BinaryWriter 
BinaryReader 

Per utilizzare questi, prima si acquista il vostro flusso, quindi si crea una delle classi di cui sopra e di associarla con il flusso. Per esempio.

MemoryStream memoryStream = new MemoryStream(); 
StreamWriter myStreamWriter = new StreamWriter(memoryStream); 

StreamReader e StreamWriter conversione tra tipi nativi e le loro rappresentazioni di stringa poi trasferire le stringhe da e per il flusso di byte. Quindi

myStreamWriter.Write(123); 

scriverà "123" (tre caratteri '1', '2' poi '3') allo stream. Se hai a che fare con file di testo (ad es. Html), StreamReader e StreamWriter sono le classi che useresti.

considerando

myBinaryWriter.Write(123); 

scriverà quattro byte che rappresentano il valore intero di 32 bit 123 (0X7B, 0x00, 0x00, 0x00). Se hai a che fare con file binari o protocolli di rete, BinaryReader e BinaryWriter sono quelli che potresti usare. (Se si stanno scambiando dati con reti o altri sistemi, è necessario prestare attenzione allo , ma questo è un altro post.)

2

Il flusso è solo un'astrazione (o un wrapper) su un flusso di byte da physical. Questo flusso physical si chiama base stream. Quindi esiste sempre un flusso di base su cui viene creato un wrapper di flusso e quindi il wrapper prende il nome dal tipo di flusso di base, ovvero FileStream, MemoryStream, ecc.

Il vantaggio del wrapper di streaming è che si ottiene una API unificata per interagire con i flussi di qualsiasi tipo sottostante usb, file ecc

perché si trattare i dati come flusso - perché blocchi di dati vengono caricati su richiesta, siamo in grado di ispezionare/processo i dati come blocchi invece di caricare tutti i dati in memoria.Questo è il modo in cui la maggior parte dei programmi si occupa di file di grandi dimensioni, ad esempio la crittografia di un file immagine del sistema operativo.

Problemi correlati