2011-10-16 62 views
6

它在这里说msdn.microsoft.com/en-us/library/system.io.stream.read.aspx表示Stream.ReadStream.Write方法都自动提前在流中的位置/偏移量为什么这里的例子http://msdn.microsoft.com/en-us/library/system.io.stream.read.aspxhttp://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

......什么? –

+0

Stream中的内部偏移量与在缓冲区和流之间读取/写入数据时需要关心的偏移量/长度(可能是2.流)之间存在差异。 – nos

+0

@sehe:责备你的操作系统。 –

回答

4

编辑(在编辑的问题):

在没有你粘贴到我看不到任何流偏移被设置问题的代码片段。

我认为你错误的字节计算读取与接收字节。这个协议可能看起来很有趣(为什么你会收到比请求更少的字节?),但是当你考虑到你可能正从高延迟的面向数据包的源读取(想想:网络套接字)时,它是有意义的。

您可能在一次突发中(来自TCP数据包)接收到6个字符,并且在下次读取时(下一个数据包到达时)只接收剩余的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); 
     } 

看来,编码器使用事先了解有关底层流实现,即stream.Read总是返回0 大小请求。这对我来说似乎是一个冒险的赌注。但如果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的呼叫。您可能会将流向位置的偏移量混淆到数据缓冲区中?

+1

我不是在谈论写部分,我的意思是阅读部分。我将MS示例与http://www.dotnetperls.com/decompress – Jonas

+1

@Jonas进行了比较:并且我也提供了GZipStream示例,现在 – sehe

+0

哦,我明白了's.Read(bytes,numBytesRead,10);'是实际上是字节缓冲区的偏移量?所以'numBytesRead'设置缓冲区内的位置,而不是流。 – Jonas

9

偏移量实际上是缓冲区的偏移量,而不是流。流在读取时自动升级。

相关问题