C# 如何简化 BinaryReader 的网络字节顺序转换?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/123918/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 14:38:56  来源:igfitidea点击:

How can one simplify network byte-order conversion from a BinaryReader?

提问by Zach Lute

System.IO.BinaryReader reads values in a little-endian format.

System.IO.BinaryReader 以小端格式读取值。

I have a C# application connecting to a proprietary networking library on the server side. The server-side sends everything down in network byte order, as one would expect, but I find that dealing with this on the client side is awkward, particularly for unsigned values.

我有一个 C# 应用程序连接到服务器端的专有网络库。正如人们所期望的那样,服务器端以网络字节顺序发送所有内容,但我发现在客户端处理这个问题很尴尬,尤其是对于无符号值。

UInt32 length = (UInt32)IPAddress.NetworkToHostOrder(reader.ReadInt32());

is the only way I've come up with to get a correct unsigned value out of the stream, but this seems both awkward and ugly, and I have yet to test if that's just going to clip off high-order values so that I have to do fun BitConverter stuff.

是我想出的从流中获取正确的无符号值的唯一方法,但这看起来既尴尬又难看,我还没有测试这是否只是要剪掉高阶值,以便我有做有趣的 BitConverter 的东西。

Is there some way I'm missing short of writing a wrapper around the whole thing to avoid these ugly conversions on every read? It seems like there should be an endian-ness option on the reader to make things like this simpler, but I haven't come across anything.

有什么方法可以让我在整个过程中编写一个包装器来避免每次读取时发生这些丑陋的转换?似乎读者应该有一个字节序选项来使这样的事情更简单,但我没有遇到任何事情。

采纳答案by Nick

There is no built-in converter. Here's my wrapper (as you can see, I only implemented the functionality I needed but the structure is pretty easy to change to your liking):

没有内置转换器。这是我的包装器(如您所见,我只实现了我需要的功能,但结构很容易根据您的喜好进行更改):

/// <summary>
/// Utilities for reading big-endian files
/// </summary>
public class BigEndianReader
{
    public BigEndianReader(BinaryReader baseReader)
    {
        mBaseReader = baseReader;
    }

    public short ReadInt16()
    {
        return BitConverter.ToInt16(ReadBigEndianBytes(2), 0);
    }

    public ushort ReadUInt16()
    {
        return BitConverter.ToUInt16(ReadBigEndianBytes(2), 0);
    }

    public uint ReadUInt32()
    {
        return BitConverter.ToUInt32(ReadBigEndianBytes(4), 0);
    }

    public byte[] ReadBigEndianBytes(int count)
    {
        byte[] bytes = new byte[count];
        for (int i = count - 1; i >= 0; i--)
            bytes[i] = mBaseReader.ReadByte();

        return bytes;
    }

    public byte[] ReadBytes(int count)
    {
        return mBaseReader.ReadBytes(count);
    }

    public void Close()
    {
        mBaseReader.Close();
    }

    public Stream BaseStream
    {
        get { return mBaseReader.BaseStream;  }
    }

    private BinaryReader mBaseReader;
}

Basically, ReadBigEndianBytes does the grunt work, and this is passed to a BitConverter. There will be a definite problem if you read a large number of bytes since this will cause a large memory allocation.

基本上,ReadBigEndianBytes 完成了繁重的工作,并将其传递给 BitConverter。如果读取大量字节,肯定会出现问题,因为这会导致大量内存分配。

回答by Cody Brocious

I built a custom BinaryReader to handle all of this. It's available as part of my Nextem library. It also has a very easy way of defining binary structs, which I think will help you here -- check out the Examples.

我构建了一个自定义的 BinaryReader 来处理所有这些。它可以作为我的 Nextem 库的一部分使用。它还具有定义二进制结构的非常简单的方法,我认为这会在这里对您有所帮助——请查看示例。

Note: It's only in SVN right now, but very stable. If you have any questions, email me at cody_dot_brocious_at_gmail_dot_com.

注意:它现在只在 SVN 中,但非常稳定。如果您有任何问题,请发送电子邮件至 cody_dot_brocious_at_gmail_dot_com。