设置流中的偏移量

发布于 12-10 05:49 字数 1531 浏览 0 评论 0原文

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

It says here msdn.microsoft.com/en-us/library/system.io.stream.read.aspx that the Stream.Read and Stream.Write methods both advance the position/offset in the stream automatically so why is the examples here http://msdn.microsoft.com/en-us/library/system.io.stream.read.aspx and http://msdn.microsoft.com/en-us/library/system.io.filestream.read.aspx manually changing the offset?

Do you only set the offset in a loop if you know the size of the stream and set it to 0 if you don't know the size and using a buffer?

   // 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;
    }

and

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

时光与爱终年不遇2024-12-17 05:49:35

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

The offset is actually the offset of the buffer, not the stream. Streams are advanced automatically as they are read.

吾家有女初长成2024-12-17 05:49:35

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

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

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

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

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


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

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

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

Edit (to the edited question):

In none of the code snippets you pasted into the question I see any stream offset being set.

I think you are mistaking the calculation of bytes to read vs. bytes received. This protocol may seem funny (why would you receive fewer bytes than requested?) but it makes sense when you consider that you might be reading from a high-latency packet oriented source (think: network sockets).

You might be receiving 6 characters in one burst (from a TCP packet) and only receive the remaining 4 characters in your next read (when the next packet has arrived).

Edit In response to your linked example from the comment:

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);
        }

It appears that the coders use prior knowledge about the underlying stream implementation, that stream.Read will always return 0 OR the size requested. That seems like a risky bet, to me. But if the docs for GZipStream do state that, it could be alright. However, since the MSDN samples use a generic Stream variable, it is (way) more correct to check the exact number of bytes read.


The first linked example uses a MemoryStream in both Write and Read fashion. The position is reset in between, so the data that was written first will be read:

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

The second example linked does not set the stream position. You'd typically have seen a call to Seek if it did. You maybe confusing the offsets into the data buffer with the stream position?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文