2012-10-23 8 views
11

Stream.CopyToを使用して、特定のバイト数だけを宛先ストリームにコピーする方法はありますか?何が最良の回避策ですか?Stream.CopyToを使用して特定のバイト数のみをコピーする方法はありますか?

編集:
私の回避策(いくつかのコードは省略):その後、

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

コピーするnバイト:

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

そのバイト数を読み取り、それを宛先ストリームに書き込みますか? – carlosfigueira

答えて

10

copying streamsの実装はあまり複雑ではありません。あなたは既存の方法を微調整するにはあまりにも難しいことではありませんバイトの唯一の一定数をコピーし、それを調整する場合は、この

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

のようなものはbytes > 0のチェックは、おそらく厳密には必要ではありませんが、害を及ぼすことはできません。

+1

4GBを超えるストリームをサポートするには、intパラメータをlongパラメータに変更してから、Math.Min関数のintにキャストします。 –

4

何がちょうどバッファを使用して、あなたが必要とするバイトをコピーすることが悪いですの?

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

私はあなたのコードをより明確にするために関数にコードをラップしました。あなたが望んでいなければそれをロールバックすることができます。 –

+0

私は私の実装を好むと思うが、それは本質的に同じことを行うので、私はまだこれをupvoted :) – Justin

+0

ジャスティン - あなたの実装は良いですが、私は離れて、スタート(私が知っているペタニック)。私は自分が好きです。なぜなら、コピーされたバイトの総数を追跡しています。それは、bytesRequiredと同じでない場合に重要になる可能性があります。あなたの関数の型 'bytes'を 'long'に変更して完了させてください。 Upvoted :) –

関連する問題