2012-10-23 13 views
11

Czy istnieje sposób użycia Stream.CopyTo do skopiowania tylko określonej liczby bajtów do strumienia docelowego? jakie jest najlepsze rozwiązanie?Jakikolwiek sposób użyć Stream.CopyTo do skopiowania tylko określonej liczby bajtów?

Edit:
Moja obejście (niektóre kod pominięta):

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;    
     } 
} 

następnie skopiować n bajtów:

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

Odczytaj tę liczbę bajtów i zapisz je w strumieniu docelowym? – carlosfigueira

Odpowiedz

10

Implementacja copying streams nie jest zbyt skomplikowana. Jeśli chcesz, aby dostosować go do kopiowania tylko pewną liczbę bajtów, to nie powinno być zbyt trudne, aby dostosować istniejące metody, coś w tym

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; 
    } 
} 

Czek dla bytes > 0 prawdopodobnie nie jest to bezwzględnie konieczne, ale nie może wyrządzić żadnej szkody.

+1

Aby obsłużyć strumienie powyżej 4 GB, powinieneś po prostu zmienić parametr int na długi parametr, a następnie przesłać go do int w funkcji Math.Min. –

4

Co w tym złego prostu kopiowanie bajtów czego potrzebujesz stosując bufor?

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

Zawijam twój kod do funkcji, aby było bardziej zrozumiałe, możesz go wycofać, jeśli tego nie chcesz. –

+0

Myślę, że wolę moją implementację, ale wciąż przegłosowałem tę, ponieważ w zasadzie robi to samo :) – Justin

+0

Justin - twoja implementacja jest dobra, podoba mi się ta chwila, która zrywa z przerwą, nawet jeśli dodaje dodatkowe porównanie początek (pedantyczny, którego znam). Lubię moje, ponieważ śledzi całkowitą liczbę skopiowanych bajtów, które mogą być ważne, jeśli nie są takie same jak bytesRequired. Wystarczy zmienić typ "bajtów" w funkcji na "długi", aby zakończyć. Awansowany :) –

Powiązane problemy