2015-10-26 135 views
0

它聲明,通過使用Stream.SetLength該流是截斷source如何在不截斷的情況下設置流的長度?

我需要設置流的長度而不截斷。

任何內置的可能性?

UPDATE: 我需要讀取文件的子集。 的文件格式:大小+數據(字符串格式)。

im使用StreamReader

UPDATE2: 林也veryintrested使用ReadLineStreamReader類。

+4

那麼你期望發生什麼? – SLaks

+3

您錯過了句子的關鍵部分,「*如果指定的值小於當前流*的長度,則該流將被截斷。」如果您將長度設置爲小於當前長度,那麼它應該做些什麼? –

+0

你試圖解決什麼樣的總體問題? – GreatAndPowerfulOz

回答

2

我需要閱讀文件

確定的一個子集,所以你不希望實際設定的長度。你想讀一個特定的長度。

寫一個Stream子類,它只讀取一定數量的字節。然後,你可以用這個類包裝文件流,StreamReader就可以工作。

或者,如果緩存中的數據就OK了,你這樣做:

var limitedStream = new MemoryStream(new BinaryReader(myStream).ReadBytes(length)); 
0

我同意@ USR的有關創建一個子流封裝的答案。以下是一個將所有調用轉發給「內部」流的示例實現,但在閱讀期間或詢問長度時涉及到。涉及寫入的任何內容都不受此實現的支持。

我還沒有完全測試這個實現,我歡迎來自社區編輯:

sealed class StreamReadLimitLengthWrapper : Stream 
{ 
    readonly Stream m_innerStream; 
    readonly long m_endPosition; 

    public StreamReadLimitLengthWrapper(Stream innerStream, int size) 
    { 
     if (innerStream == null) throw new ArgumentNullException("innerStream"); 
     if (size < 0) throw new ArgumentOutOfRangeException("size"); 

     m_innerStream = innerStream; 
     m_endPosition = m_innerStream.Position + size; 
    } 

    public override bool CanRead 
    { 
     get { return m_innerStream.CanRead; } 
    } 

    public override bool CanSeek 
    { 
     get { return m_innerStream.CanSeek; } 
    } 

    public override bool CanWrite 
    { 
     get { return false; } 
    } 

    public override void Flush() 
    { 
     m_innerStream.Flush(); 
    } 

    public override long Length 
    { 
     get { return m_endPosition; } 
    } 

    public override long Position 
    { 
     get 
     { 
      return m_innerStream.Position; 
     } 
     set 
     { 
      m_innerStream.Position = value; 
     } 
    } 

    public override int Read(byte[] buffer, int offset, int count) 
    { 
     count = GetAllowedCount(count); 
     return m_innerStream.Read(buffer, offset, count); 
    } 

    public override long Seek(long offset, SeekOrigin origin) 
    { 
     return m_innerStream.Seek(offset, origin); 
    } 

    public override void SetLength(long value) 
    { 
     throw new NotSupportedException(); 
    } 

    public override void Write(byte[] buffer, int offset, int count) 
    { 
     throw new NotSupportedException(); 
    } 

    public override bool CanTimeout { get { return m_innerStream.CanTimeout; } } 

    public override int ReadTimeout 
    { 
     get 
     { 
      return m_innerStream.ReadTimeout; 
     } 
     set 
     { 
      m_innerStream.ReadTimeout = value; 
     } 
    } 

    public override int WriteTimeout 
    { 
     get 
     { 
      return m_innerStream.ReadTimeout; 
     } 
     set 
     { 
      m_innerStream.ReadTimeout = value; 
     } 
    } 

    public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) 
    { 
     count = GetAllowedCount(count); 
     return m_innerStream.BeginRead(buffer, offset, count, callback, state); 
    } 

    public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) 
    { 
     throw new NotSupportedException(); 
    } 

    public override void Close() 
    { 
     // Since this wrapper does not own the underlying stream, we do not want it to close the underlying stream 
    } 

    public override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken) 
    { 
     return m_innerStream.CopyToAsync(destination, bufferSize, cancellationToken); 
    } 

    public override int EndRead(IAsyncResult asyncResult) 
    { 
     return m_innerStream.EndRead(asyncResult); 
    } 

    public override Task FlushAsync(CancellationToken cancellationToken) 
    { 
     return m_innerStream.FlushAsync(cancellationToken); 
    } 

    public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) 
    { 
     count = GetAllowedCount(count); 
     return m_innerStream.ReadAsync(buffer, offset, count, cancellationToken); 
    } 

    public override int ReadByte() 
    { 
     int count = GetAllowedCount(1); 
     if (count == 0) 
      return -1; 

     return m_innerStream.ReadByte(); 
    } 

    public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) 
    { 
     throw new NotSupportedException(); 
    } 

    public override void WriteByte(byte value) 
    { 
     throw new NotSupportedException(); 
    } 

    private int GetAllowedCount(int count) 
    { 
     long pos = m_innerStream.Position; 
     long maxCount = m_endPosition - pos; 
     if (count > maxCount) 
      count = (int)maxCount; 
     return count; 
    } 
} 
0

你問錯了問題在這裏。流的Length是已知數量的字節可用於從流中讀取。設置流的長度將更改源以確保使用指定的長度。


由於您只是想限制您從流中讀取多少內容,只需根據需要閱讀並關閉即可。你不需要做其他事情。

由於看起來您正在嘗試讀取文本文件,只需按照正常的文件讀取模式進行操作即可獲得適當的停止條件。你甚至不需要流,File類提供了簡單的方法來讀取文件的行。

foreach (var line in File.ReadLines(path)) 
{ 
    // do something with line... 
    if (line == "end of interesting section") 
     break; 
} 
相關問題