它表示,使用Stream.SetLength
流是截断。
source
我需要设置流的长度而不用截断。
任何内置的可能性?
更新: 我需要读取文件的子集。 文件格式:size + data(字符串格式)。
我正在使用StreamReader
UPDATE2 :
我也非常有兴趣使用ReadLine
课程中的StreamReader
。
答案 0 :(得分:2)
我需要读取文件的子集
好的,所以你不想实际设置长度。你想读一个特定的长度。
给自己写一个只读取一定数量字节的Stream
子类。然后,您可以使用该类包装文件流,StreamReader
将正常工作。
或者,如果缓冲数据正常,则执行以下操作:
var limitedStream = new MemoryStream(new BinaryReader(myStream).ReadBytes(length));
答案 1 :(得分:0)
我同意@ usr关于创建子类Stream包装器的答案。这是一个示例实现,它将所有调用转发到“内部”流,但在读取期间或在询问长度时会参与其中。任何涉及写作的内容都不受此实现的支持。
我尚未对此实施进行全面测试,欢迎来自社区的修改:
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;
}
}
答案 2 :(得分:0)
你在这里问错了。流的Length
是可从流中读取的已知字节数。设置流的长度会改变源,以确保它使用指定的长度。
由于您只想限制从流中读取的内容,因此只需根据需要进行阅读并关闭它即可。你不需要做任何其他事情。
由于您似乎正在尝试读取文本文件,因此请使用正常的文件读取模式并提出适当的停止条件。您甚至不需要流,File
类提供了读取文件行的简单方法。
foreach (var line in File.ReadLines(path))
{
// do something with line...
if (line == "end of interesting section")
break;
}