我们假设我有以下方法:
void Upload(Stream stream)
{
// uploads the content of the specified stream somewhere
}
让我们进一步假设我得到了一些二进制文件f
,其中包含一些我想用上述方法上传的数据。
但是:它不是我要上传的整个文件。它只是f
的某个部分。更准确地说,所需数据从某个位置s >= 0
开始,到达某个位置e <= f.Length
。
有没有办法传递Stream
实例,该实例从位置s
开始,长度为e
,而不会复制s
和{{之间的所有字节1}}进入新的流实例?我问,因为有可能,文件e
非常大,我不想对潜在的可用内存进行假设。
答案 0 :(得分:2)
请考虑使用Stream.CanSeek Property,Stream.Position Property,Stream.Seek Method来“访问”流的特定部分。
要拥有一个具有适当长度的单独Stream
实例,似乎需要实现一个SubStream
类 - 表示子流的包装器。以下引用对于实现这样的包装器非常有用:
答案 1 :(得分:1)
如果在调用方法之前修改原始流中的指针,则使用Seek设置起始位置,使用SetLength设置结束位置。然后,您可以将流传递给方法,它应该只触摸该部分(假设它不在内部寻找回到开头)。
不幸的是,SetLength
会截断流,因此如果您出于某种原因需要,您将无法再访问其余部分。但是,如果这不是一项要求,那么这应该有效。
编辑:由于您需要保留原始流,这些是我能想到的其他选项:
您可以将所需的部分复制到新的流中,例如MemoryStream
。您不需要复制整个文件,但您需要使用Seek和Read复制要上传的部分。
byte[] data = new byte[size];
stream.Seek(position, SeekOrigin.Begin);
stream.Read(data, 0, size);
using (MemoryStream subStream = new MemoryStream(data))
{
Upload(subStream);
}
您可以编写自己的流实现来执行您想要的操作,只访问另一个流的特定部分。