2011-08-04 13 views
5

मेरे पास एक स्ट्रीम है जिसमें डेटा के कई टुकड़े हैं। मैं उस डेटा के एक टुकड़े को किसी अन्य स्ट्रीम में बेनकाब करना चाहता हूं। मैं जिस डेटा को निकालना चाहता हूं उसका टुकड़ा अक्सर 100 एमबी से अधिक हो सकता है। चूंकि मेरे पास पहले से डेटा के साथ स्ट्रीम है, इसलिए यह उस डेटा को दूसरी स्ट्रीम में कॉपी करने और उसे वापस करने के लिए अपशिष्ट की तरह लगता है। जो मैं देख रहा हूं वह पहली धारा में डेटा को संदर्भित करने का एक तरीका है, जबकि यह नियंत्रित करता है कि दूसरी धारा कितनी संदर्भ दे सकती है। क्या यह संभव हैकिसी उपयोगकर्ता को मेरी स्ट्रीम के उपधारा का खुलासा कैसे करें

उत्तर

4

आपको अपनी खुद की स्ट्रीम क्लास बनाने की आवश्यकता है जो इसकी स्थिति को मान्य करता है और वांछित सबसेट देता है।

मुझे ऐसा करने वाले किसी भी अंतर्निहित कक्षाओं से अवगत नहीं है।

+0

तो अब मेरे काम शुरू होता है ... – QueueHammer

0

डुप्लिकेटिंग से आपको क्या डर लगता है? मुझे संदेह है कि आपके पास कुछ भी शानदार प्रदर्शन महत्वपूर्ण है, फ्लाई पर अपने स्ट्रीम को पार्स करें और मेमोरीस्ट्रीम का उपयोग करें जब तक आपको लगता है कि आपको कुछ और चाहिए।

+4

मैं डेटा के mesgs के सैकड़ों को कॉपी किया जाएगा, और स्मृति में एक अन्य जगह पर कॉपी करने के लिए है कि नहीं करना चाहती। विशेष रूप से यदि व्यक्ति कई सौ मेग खंडों का अनुरोध करने जा रहा है। इसके अलावा यह नकल का डर नहीं है, यदि वे मौजूद हैं तो अन्य वर्गों का पुन: उपयोग करने के लिए प्रोग्रामिंग का अभ्यास है। – QueueHammer

0

ऐसा लगता है कि StreamMuxer प्रोजेक्ट को इसी तरह के उद्देश्य से बनाया गया था।

+0

यह अच्छा लग रहा है। मेरी इच्छा है कि कोड प्रोजेक्ट गिट हब के साथ काम करे। ब्याज का थोड़ा सा संघर्ष। – QueueHammer

3

मार्क ग्रेवेल 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(); 
    } 
} 
संबंधित मुद्दे