【问题标题】:Setting the offset in a stream设置流中的偏移量
【发布时间】:2011-10-16 21:35:47
【问题描述】:

这里说 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();
    }
}

【问题讨论】:

  • Stream 中的内部偏移量与您在缓冲区和流之间读取/写入数据时需要关心的偏移量/长度之间存在差异,可能还有 2. 流。
  • @nos: 2. 是日耳曼语:说英语(实际上也包括其他语言)的人不会看到它的意思是“第二”。请改用2ndsecond
  • @IgnacioVazquez-Abrams:所以现在 Opera 是我的操作系统 - 哈哈。 Chrome/FF 确实可以在同一系统上渲染它。 (另外:我怪你试图通过 &zwsp; -es 欺骗来规避 cmets 的最小长度政策)

标签: c# .net stream


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    编辑(对已编辑的问题):

    在您粘贴到问题中的任何代码 sn-ps 中,我都没有看到任何流偏移被设置。

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

    您可能会在一次突发中收到 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);
            }
    

    似乎编码人员使用了有关底层流实现的先验知识,即 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;
    

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

    【讨论】:

    • 我说的不是写部分,我是说读部分。我将 MS 示例与 dotnetperls.com/decompress 进行比较
    • @Jonas:我现在也解决 GZipStream 示例
    • 哦,我明白了,s.Read(bytes, numBytesRead, 10); 实际上是字节缓冲区的偏移量?所以numBytesRead 设置的是缓冲区中的位置,而不是流。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多