在流中设置偏移量

Jon*_*nas 6 .net c# stream

它在这里说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;
    }
Run Code Online (Sandbox Code Playgroud)

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 9

偏移实际上是缓冲区的偏移量,而不是流.流在读取时会自动前进.


seh*_*ehe 5

编辑(编辑后的问题):

在您粘贴到问题中的任何代码片段中,我都没有看到设置了任何流偏移量。

我认为您错误地计算了要读取的字节与接收到的字节。该协议可能看起来很有趣(为什么您收到的字节数少于请求的字节数?),但是当您考虑到您可能正在从面向高延迟数据包的源(例如:网络套接字)读取数据时,它就有意义了。

您可能会在一次突发中接收 6 个字符(来自 TCP 数据包),而在下一次读取时(当下一个数据包到达时)仅收到剩余的 4 个字符。

编辑响应评论中的链接示例:

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);
        }
Run Code Online (Sandbox Code Playgroud)

看来编码人员使用了有关底层流实现的先验知识,stream.Read 将始终返回 0请求的大小。对我来说,这似乎是一个冒险的赌注。但如果文档确实GZipStream说明了这一点,那就没问题了。但是,由于 MSDN 示例使用通用Stream变量,因此检查读取的确切字节数更为正确。


第一个链接的示例以写入和读取方式使用 MemoryStream。中间位置被重置,因此首先写入的数据将被读取:

    Stream s = new MemoryStream();
    for (int i = 0; i < 100; i++)
    {
        s.WriteByte((byte)i);
    }
    s.Position = 0;
Run Code Online (Sandbox Code Playgroud)

链接的第二个示例未设置流位置。Seek如果确实如此,您通常会看到一个调用。您可能会将数据缓冲区的偏移量与流位置混淆?