在这里说msdn.microsoft.com/en-us/library/system.io.stream.read.aspx,Stream.Read
和Stream.Write
方法都提升了流中的位置/偏移量自动为什么这里的示例http://msdn.microsoft.com/en-us/library/system.io.stream.read.aspx和http://msdn.microsoft.com/en-us/library/system.io.filestream.read.aspx会手动更改偏移量?
如果您知道流的大小,是否只在循环中设置偏移量,如果您不知道大小并使用缓冲区,则将其设置为0?
// Now read s into a byte buffer.
byte[] bytes = new byte[s.Length];
int numBytesToRead = (int) s.Length;
int numBytesRead = 0;
while (numBytesToRead > 0)
{
// Read may return anything from 0 to 10.
int n = s.Read(bytes, numBytesRead, 10);
// The end of the file is reached.
if (n == 0)
{
break;
}
numBytesRead += n;
numBytesToRead -= n;
}
和
using (GZipStream stream = new GZipStream(new MemoryStream(gzip), CompressionMode.Decompress))
{
const int size = 4096;
byte[] buffer = new byte[size];
using (MemoryStream memory = new MemoryStream())
{
int count = 0;
do
{
count = stream.Read(buffer, 0, size);
if (count > 0)
{
memory.Write(buffer, 0, count);
}
}
while (count > 0);
return memory.ToArray();
}
}
答案 0 :(得分:9)
偏移实际上是缓冲区的偏移量,而不是流。流在读取时会自动前进。
答案 1 :(得分:4)
修改(编辑后的问题):
在您粘贴到问题中的所有代码段中,我都看不到设置了任何流偏移。
我认为你错误地计算了读取的字节数和接收的字节数。这个协议看起来很有趣(为什么你会收到比请求更少的字节?)但是当你考虑到你可能正在从一个高延迟的数据包导向源(想想:网络套接字)中读取它时,这是有道理的。
您可能在一次突发中接收6个字符(来自TCP数据包),并且只在下次读取时接收剩余的4个字符(当下一个数据包到达时)。
修改以回复评论中的linked example:
using (GZipStream stream = new GZipStream(new MemoryStream(gzip), CompressionMode.Decompress))
{
// ... snip
count = stream.Read(buffer, 0, size);
if (count > 0)
{
memory.Write(buffer, 0, count);
}
似乎编码员使用有关基础流实现的先验知识,该流将始终返回0 OR 所请求的大小。对我来说,这似乎是一个冒险的赌注。但是,如果GZipStream
的文档确实说明了这一点,那就可以了。但是,由于MSDN示例使用通用Stream
变量,因此检查读取的确切字节数更为正确。
第一个链接示例以Write和Read方式使用MemoryStream。位置在两者之间重置,因此首先写入的数据将被读取:
Stream s = new MemoryStream();
for (int i = 0; i < 100; i++)
{
s.WriteByte((byte)i);
}
s.Position = 0;
链接的第二个示例不设置流位置。如果确实如此,您通常会看到Seek
的来电。您可能会使用流位置将偏移混淆到数据缓冲区中?