2011-10-16 9 views
6

Si dice qui msdn.microsoft.com/en-us/library/system.io.stream.read.aspx che i metodi Stream.Read e Stream.Write fanno avanzare automaticamente la posizione/l'offset nel flusso in modo tale perché gli esempi qui http://msdn.microsoft.com/en-us/library/system.io.stream.read.aspx e http://msdn.microsoft.com/en-us/library/system.io.filestream.read.aspx cambiano manualmente l'offset?Impostazione dell'offset in un flusso

si fa a impostare solo l'offset in un ciclo se si conosce la dimensione del flusso e impostarlo a 0 se non si conosce la dimensione e l'utilizzo di un buffer?

// Now read s into a byte buffer. 
    byte[] bytes = new byte[s.Length]; 
    int numBytesToRead = (int) s.Length; 
    int numBytesRead = 0; 
    while (numBytesToRead > 0) 
    { 
     // Read may return anything from 0 to 10. 
     int n = s.Read(bytes, numBytesRead, 10); 
     // The end of the file is reached. 
     if (n == 0) 
     { 
      break; 
     } 
     numBytesRead += n; 
     numBytesToRead -= n; 
    } 

e

using (GZipStream stream = new GZipStream(new MemoryStream(gzip), CompressionMode.Decompress)) 
{ 
    const int size = 4096; 
    byte[] buffer = new byte[size]; 
    using (MemoryStream memory = new MemoryStream()) 
    { 
    int count = 0; 
    do 
    { 
     count = stream.Read(buffer, 0, size); 
     if (count > 0) 
     { 
     memory.Write(buffer, 0, count); 
     } 
    } 
    while (count > 0); 
    return memory.ToArray(); 
    } 
} 
+0

... Che cosa? –

+0

C'è una differenza tra gli offset interni in un flusso e gli offset/le lunghezze di cui bisogna preoccuparsi quando si leggono/scrivono dati tra un buffer e uno stream, e forse uno 2. stream. – nos

+0

@sehe: incolpa il tuo sistema operativo. –

risposta

4

Modifica (alla domanda Edited):

In nessuno dei frammenti di codice che hai incollato nella domanda vedo qualsiasi flusso di offset di fase di impostazione.

Penso che si sta scambiando il calcolo di byte da leggere rispetto byte ricevuti. Questo protocollo può sembrare divertente (perché dovresti ricevere meno byte di quanto richiesto?) Ma ha senso quando pensi che potresti leggere da una sorgente orientata al pacchetto ad alta latenza (pensa: socket di rete).

Potresti ricevere 6 caratteri in un burst (da un pacchetto TCP) e ricevere solo i 4 caratteri rimanenti nella prossima lettura (quando è arrivato il prossimo pacchetto).

Modifica In risposta alla sua linked example dal commento:

using (GZipStream stream = new GZipStream(new MemoryStream(gzip), CompressionMode.Decompress)) 
    { 
     // ... snip 

     count = stream.Read(buffer, 0, size); 
     if (count > 0) 
     { 
     memory.Write(buffer, 0, count); 
     } 

Sembra che i programmatori usano conoscenza preventiva circa l'attuazione flusso sottostante, che stream.Read restituirà sempre 0 O la dimensione richiesto. Sembra una scommessa azzardata, per me. Ma se i documenti per GZipStream lo dichiarano, potrebbe andare bene. Tuttavia, poiché gli esempi MSDN utilizzano una variabile generica Stream, è (modo) più corretto per verificare il numero esatto di byte letti.


Il primo esempio collegato utilizza un MemoryStream in modalità di scrittura e lettura. La posizione viene resettato in mezzo, quindi i dati che è stato scritto prima sarà letto:

Stream s = new MemoryStream(); 
    for (int i = 0; i < 100; i++) 
    { 
     s.WriteByte((byte)i); 
    } 
    s.Position = 0; 

Il secondo esempio collegata fa non impostare la posizione di flusso. In genere avresti visto una chiamata allo Seek se lo avessi fatto. Forse confondi gli offset nel buffer dei dati con la posizione del flusso?

+1

Non sto parlando della parte di scrittura, intendo la parte letta. Stavo confrontando l'esempio MS con http://www.dotnetperls.com/decompress – Jonas

+1

@Jonas: e indirizzo anche l'esempio GZipStream, ora – sehe

+0

Oh vedo, 's.Read (bytes, numBytesRead, 10);' is in realtà l'offset per il buffer di byte? Quindi 'numBytesRead' sta impostando la posizione all'interno del buffer, non il flusso. – Jonas

9

L'offset viene effettivamente l'offset del buffer, non il flusso. Gli stream vengono avanzati automaticamente mentre vengono letti.