如何从流中准确读取 n 个字节? [英] How do I read exactly n bytes from a stream?

查看:25
本文介绍了如何从流中准确读取 n 个字节?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这比我最初想象的要棘手一些.我正在尝试从流中读取 n 个字节.

This is a little more tricky than I first imagined. I'm trying to read n bytes from a stream.

MSDN 声称Read 不必返回 n 个字节,它只需要返回至少 1 个和最多 n 个字节,其中 0 个字节是到达流末尾的特殊情况.

The MSDN claims that Read does not have to return n bytes, it just must return at least 1 and up to n bytes, with 0 bytes being the special case of reaching the end of the stream.

通常,我使用类似的东西

Typically, I'm using something like

var buf = new byte[size];
var count = stream.Read (buf, 0, size);

if (count != size) {
    buf = buf.Take (count).ToArray ();
}

yield return buf;

我希望正好是 size 字节,但根据规范 FileStream 也可以返回大量的 1 字节块.必须避免这种情况.

I'm hoping for exactly size bytes but by spec FileStream would be allowed to return a large number of 1-byte chunks as well. This must be avoided.

解决这个问题的一种方法是拥有 2 个缓冲区,一个用于读取,另一个用于收集块,直到我们获得请求的字节数.不过有点麻烦.

One way to solve this would be to have 2 buffers, one for reading and one for collecting the chunks until we got the requested number of bytes. That's a little cumbersome though.

我还查看了 BinaryReader 但它的规范也确实如此没有明确说明肯定会返回n个字节.

I also had a look at BinaryReader but its spec also does not clearly state that n bytes will be returned for sure.

澄清:当然,在流结束时,返回的字节数可能小于 size - 这不是问题.我只是在谈论不接收 n 个字节,即使它们在流中可用.

To clarify: Of course, upon the end of the stream the returned number of bytes may be less than size - that's not a problem. I'm only talking about not receiving n bytes even though they are available in the stream.

推荐答案

可读性更强的版本:

int offset = 0;
while (offset < count)
{
    int read = stream.Read(buffer, offset, count - offset);
    if (read == 0)
        throw new System.IO.EndOfStreamException();
    offset += read;
}

或者写成Stream类的扩展方法:

Or written as an extension method for the Stream class:

public static class StreamUtils
{
    public static byte[] ReadExactly(this System.IO.Stream stream, int count)
    {
        byte[] buffer = new byte[count];
        int offset = 0;
        while (offset < count)
        {
            int read = stream.Read(buffer, offset, count - offset);
            if (read == 0)
                throw new System.IO.EndOfStreamException();
            offset += read;
        }
        System.Diagnostics.Debug.Assert(offset == count);
        return buffer;
    }
}

这篇关于如何从流中准确读取 n 个字节?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆