2011-08-04 31 views
5

Tôi có luồng chứa nhiều phần dữ liệu. Tôi muốn chỉ hiển thị một phần dữ liệu đó trong luồng khác. Mảnh dữ liệu tôi muốn trích xuất thường có thể trên 100mb. Vì tôi đã có luồng với dữ liệu trong nó, nó có vẻ như một sự lãng phí để sao chép dữ liệu đó sang một luồng khác và trả về nó. Những gì đang tìm kiếm là cách để tham chiếu dữ liệu trong luồng đầu tiên trong khi kiểm soát số lượng luồng thứ hai có thể tham chiếu. Có phải điều này có thểCách hiển thị một phần phụ của luồng của tôi cho người dùng

Trả lời

4

Bạn cần tạo lớp Luồng của riêng mình để xác thực vị trí của nó và trả về tập hợp con mong muốn.

Tôi không biết bất kỳ lớp tích hợp nào thực hiện việc này.

+0

Vì vậy, bây giờ nhiệm vụ của tôi bắt đầu ... – QueueHammer

0

Chính xác bạn đang sợ sao chép? Tôi nghi ngờ bạn có bất cứ điều gì siêu hiệu suất quan trọng, phân tích Stream của bạn trên bay và sử dụng một MemoryStream cho đến khi bạn tìm thấy bạn cần cái gì khác.

+4

Tôi sẽ sao chép hàng trăm dữ liệu giá trị mesgs và không muốn sao chép dữ liệu đó sang một vị trí khác trong bộ nhớ. Cụ thể nếu người đó sẽ yêu cầu nhiều phần trăm meg. Bên cạnh đó nó không phải là một nỗi sợ hãi của sự trùng lặp, là một thực hành lập trình để tái sử dụng các lớp khác nếu chúng tồn tại. – QueueHammer

0

Có vẻ như dự án StreamMuxer đã được tạo với mục đích tương tự.

+0

Điều này có vẻ tốt. Tôi ước rằng Code Project đã làm việc với Git Hub. Có thể có xung đột lợi ích nhỏ. – QueueHammer

3

Có một sự thực hiện tốt điều này bởi Mark Gravell detailed here. Mã được đăng ở đó là:

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(); 
    } 
} 
Các vấn đề liên quan