2015-10-26 57 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; 
} 
相关问题