2012-10-23 10 views
11

Gibt es eine Möglichkeit Stream.CopyTo zu verwenden, um nur bestimmte Anzahl von Bytes in den Zieldatenstrom zu kopieren? Was ist die beste Problemumgehung?Kann Stream.CopyTo nur eine bestimmte Anzahl von Bytes kopieren?

Edit:
Meine Abhilfe (einige Code weggelassen):

internal sealed class Substream : Stream 
    { 
     private readonly Stream stream; 
     private readonly long origin; 
     private readonly long length; 
     private long position;   

     public Substream(Stream stream, long length) 
     { 
      this.stream = stream; 
      this.origin = stream.Position; 
      this.position = stream.Position; 
      this.length = length;    
     } 

public override int Read(byte[] buffer, int offset, int count) 
     { 
      var n = Math.Max(Math.Min(count, origin + length - position), 0);     
      int bytesRead = stream.Read(buffer, offset, (int) n); 
      position += bytesRead; 
      return bytesRead;    
     } 
} 

dann kopieren n Bytes:

var substream = new Substream(stream, n); 
       substream.CopyTo(stm); 
+4

Die Anzahl der Bytes lesen und in den Zieldatenstrom schreiben? – carlosfigueira

Antwort

10

Die Implementierung von copying streams ist nicht allzu kompliziert. Wenn Sie es anpassen mögen nur eine bestimmte Anzahl von Bytes zu kopieren, dann sollte es nicht allzu schwierig sein, das bestehende Verfahren zu optimieren, so etwas wie diese

public static void CopyStream(Stream input, Stream output, int bytes) 
{ 
    byte[] buffer = new byte[32768]; 
    int read; 
    while (bytes > 0 && 
      (read = input.Read(buffer, 0, Math.Min(buffer.Length, bytes))) > 0) 
    { 
     output.Write(buffer, 0, read); 
     bytes -= read; 
    } 
} 

Die Prüfung auf bytes > 0 wahrscheinlich nicht unbedingt notwendig ist, aber kann keinen Schaden anrichten.

+1

Für die Unterstützung von Datenströmen über 4 GB sollten Sie einfach den Parameter int in einen langen Parameter ändern und ihn dann in der Funktion Math.Min in int umwandeln. –

4

Was mit nur Kopieren der Bytes falsch Sie einen Puffer verwenden müssen?

long CopyBytes(long bytesRequired, Stream inStream, Stream outStream) 
{ 
    long readSoFar = 0L; 
    var buffer = new byte[64*1024]; 
    do 
    { 
     var toRead = Math.Min(bytesRequired - readSoFar, buffer.Length); 
     var readNow = inStream.Read(buffer, 0, (int)toRead); 
     if (readNow == 0) 
      break; // End of stream 
     outStream.Write(buffer, 0, readNow); 
     readSoFar += readNow; 
    } while (readSoFar < bytesRequired); 
    return readSoFar; 
} 
+0

Ich habe Ihren Code in eine Funktion eingepackt, um es klarer zu machen, Sie können es zurückrollen, wenn Sie es nicht möchten. –

+0

Ich denke, dass ich meine Implementierung bevorzuge, aber ich habe immer noch eine Upvoted, weil es im Wesentlichen das gleiche tut :) – Justin

+0

Justin - Ihre Implementierung ist gut, ich mag die while die weg mit der Pause, auch wenn es einen zusätzlichen Vergleich bei der Anfang (pedantisch ich weiß). Ich mag meinen, weil es die Gesamtzahl der kopierten Bytes verfolgt, die wichtig sein können, wenn sie nicht mit bytesRequired identisch sind. Ändern Sie einfach den Typ "Bytes" in Ihrer Funktion auf "lang" für den Abschluss. Upvoted :) –

Verwandte Themen