2011-08-04 12 views
5

多くのデータが含まれているストリームがあります。私はそのデータの一部を別のストリームに公開したいと思います。私が抽出したいデータの断片は、しばしば100MBを超えることができます。私はすでにそこにデータを持っているので、そのデータを別のストリームにコピーして返すのは無駄だと思われます。私が探しているのは、第1ストリームのデータを参照し、第2ストリームがどれだけ参照できるかを制御する方法です。これは可能ですストリームのサブセクションをユーザーに公開する方法

答えて

4

独自のStreamクラスを作成して位置を検証し、必要なサブセットを返す必要があります。

私はこれを行う組み込みクラスについて認識していません。

+0

だから今、私の仕事が始まる... – QueueHammer

0

正確に複製するのは怖いですか?私はあなたがスーパーパフォーマンスが重大であるとは思わない、あなたのストリームをその場で解析し、何か他のものが必要になるまでMemoryStreamを使用する。

+4

は、私は、データの価値mesgs数百人をコピーされるだろう、とメモリ内の別の場所にいることをコピーしたくない:コードがありました。具体的には、人が複数の100メガセクションを要求する場合です。重複の恐れではなく、他のクラスが存在する場合、それらを再利用するようにプログラミングすることです。 – QueueHammer

0

StreamMuxerのように見えますが、プロジェクトは似たような目的で作成されました。

+0

これはよさそうだ。コードプロジェクトがGit Hubと協力してくれたらと思っています。おそらく、少しの利害の衝突。 – QueueHammer

3

これは、Mark Gravell detailed hereによってうまく実装されています。

using System.IO; 
using System; 
static class Program 
{ 

// shows that we can read a subset of an existing stream... 
    static void Main() 
    { 
     byte[] buffer = new byte[255]; 
     for (byte i = 0; i < 255; i++) 
     { 
      buffer[i] = i; 
     } 
     using(MemoryStream ms = new MemoryStream(buffer)) 
     using (SubStream ss = new SubStream(ms, 10, 200)) 
     { 
      const int BUFFER_SIZE = 17; // why not... 
      byte[] working = new byte[BUFFER_SIZE]; 
      int read; 
      while ((read = ss.Read(working, 0, BUFFER_SIZE)) > 0) 
      { 
       for (int i = 0; i < read; i++) 
       { 
        Console.WriteLine(working[i]); 
       } 
      } 
     } 
    } 
} 

class SubStream : Stream 
{ 
    private Stream baseStream; 
    private readonly long length; 
    private long position; 
    public SubStream(Stream baseStream, long offset, long length) 
    { 
     if (baseStream == null) throw new ArgumentNullException("baseStream"); 
     if (!baseStream.CanRead) throw new ArgumentException("can't read base stream"); 
     if (offset < 0) throw new ArgumentOutOfRangeException("offset"); 

     this.baseStream = baseStream; 
     this.length = length; 

     if (baseStream.CanSeek) 
     { 
      baseStream.Seek(offset, SeekOrigin.Current); 
     } 
     else 
     { // read it manually... 
      const int BUFFER_SIZE = 512; 
      byte[] buffer = new byte[BUFFER_SIZE]; 
      while (offset > 0) 
      { 
       int read = baseStream.Read(buffer, 0, offset < BUFFER_SIZE ? (int) offset : BUFFER_SIZE); 
       offset -= read; 
      } 
     } 
    } 
    public override int Read(byte[] buffer, int offset, int count) 
    { 
     CheckDisposed(); 
     long remaining = length - position; 
     if (remaining <= 0) return 0; 
     if (remaining < count) count = (int) remaining; 
     int read = baseStream.Read(buffer, offset, count); 
     position += read; 
     return read; 
    } 
    private void CheckDisposed() 
    { 
     if (baseStream == null) throw new ObjectDisposedException(GetType().Name); 
    } 
    public override long Length 
    { 
     get { CheckDisposed(); return length; } 
    } 
    public override bool CanRead 
    { 
     get { CheckDisposed(); return true; } 
    } 
    public override bool CanWrite 
    { 
     get { CheckDisposed(); return false; } 
    } 
    public override bool CanSeek 
    { 
     get { CheckDisposed(); return false; } 
    } 
    public override long Position 
    { 
     get { 
      CheckDisposed(); 
      return position; 
     } 
     set { throw new NotSupportedException(); } 
    } 
    public override long Seek(long offset, SeekOrigin origin) 
    { 
     throw new NotSupportedException(); 
    } 
    public override void SetLength(long value) 
    { 
     throw new NotSupportedException(); 
    } 
    public override void Flush() 
    { 
     CheckDisposed(); baseStream.Flush(); 
    } 
    protected override void Dispose(bool disposing) 
    { 
     base.Dispose(disposing); 
     if (disposing) 
     { 
      if (baseStream != null) 
      { 
       try { baseStream.Dispose(); } 
       catch { } 
       baseStream = null; 
      } 
     } 
    } 
    public override void Write(byte[] buffer, int offset, int count) 
    { 
     throw new NotImplementedException(); 
    } 
} 
関連する問題