对于不从 0 开始的缓冲区,是否有一种不那么痛苦的 GetBytes 方法?

发布于 2024-08-26 22:35:51 字数 345 浏览 11 评论 0 原文

我必须处理项目中的原始字节,我基本上需要做这样的事情,

byte[] ToBytes(){
  byte[] buffer=new byte[somelength];
  byte[] tmp;
  tmp=BitConverter.GetBytes(SomeShort);
  buffer[0]=tmp[0];
  buffer[1]=tmp[1];
  tmp=BitConverter.GetBytes(SomeOtherShort);
  buffer[2]=tmp[0];
  buffer[3]=tmp[1];
}

我觉得这是非常错误的,但我找不到任何更好的方法来做到这一点。有更简单的方法吗?

I am having to deal with raw bytes in a project and I need to basically do something like this

byte[] ToBytes(){
  byte[] buffer=new byte[somelength];
  byte[] tmp;
  tmp=BitConverter.GetBytes(SomeShort);
  buffer[0]=tmp[0];
  buffer[1]=tmp[1];
  tmp=BitConverter.GetBytes(SomeOtherShort);
  buffer[2]=tmp[0];
  buffer[3]=tmp[1];
}

I feel like this is so wrong yet I can't find any better way of doing it. Is there an easier way?

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

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

发布评论

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

评论(5

初心未许 2024-09-02 22:35:51

BinaryWriter 非常高效:

    byte[] ToBytes() {
        var ms = new MemoryStream(somelength);
        var bw = new BinaryWriter(ms);
        bw.Write(SomeShort);
        bw.Write(SomeOtherShort);
        return ms.ToArray();
    }

BinaryWriter is very efficient:

    byte[] ToBytes() {
        var ms = new MemoryStream(somelength);
        var bw = new BinaryWriter(ms);
        bw.Write(SomeShort);
        bw.Write(SomeOtherShort);
        return ms.ToArray();
    }
独行侠 2024-09-02 22:35:51

您不需要将 tmp 初始化为新数组。 BitConverter.GetBytes 创建一个新数组并为您返回它。对于 GetBytes 您无能为力,但您可以使用 Buffer.BlockCopy 来简化复制操作。

如果您不是在性能关键的代码段中执行此操作,则可以使用一点 LINQy 并执行以下操作:

IEnumerable<byte> bytes = BitConverter.GetBytes(first);
bytes = bytes.Concat(BitConverter.GetBytes(second));
bytes = bytes.Concat(BitConverter.GetBytes(third));
// ... so on; you can chain the calls too
return bytes.ToArray();

You don't need to initialize tmp to a new array. BitConverter.GetBytes creates a new array and returns it for you. There's not much you can do about GetBytes but you can use methods like Buffer.BlockCopy to simplify the copy operation.

If you're not doing this in a performance-critical piece of code, you can go a bit LINQy and do things like:

IEnumerable<byte> bytes = BitConverter.GetBytes(first);
bytes = bytes.Concat(BitConverter.GetBytes(second));
bytes = bytes.Concat(BitConverter.GetBytes(third));
// ... so on; you can chain the calls too
return bytes.ToArray();
心安伴我暖 2024-09-02 22:35:51

如果您事先知道大小(有一组值类型),则可以使用结构体并在结构体中分配值。然后使用不安全代码复制原始字节。我仍然建议不要这样做,除非出于速度目的确实有必要。你可能会认为这很痛苦:)

private struct MyStruct
{
    public short A;
    public short B;

    public MyStruct(short a, short b)
    {
        A = a;
        B = b;
    }
}

private unsafe byte[] UnsafeStruct(MyStruct myStruct)
{
    byte[] buffer = new byte[4]; // where 4 is the size of the struct
    fixed (byte* ptr = buffer)
    {
        *((MyStruct*)ptr) = myStruct;
    }
    return buffer;
}

If you know the size beforehand (have a set of value types) you could use a struct and assign your values in the struct. Then use unsafe code to copy the raw bytes. I would still advise against it unless it's really necessary for speed purposes. And you might think it's painful :)

private struct MyStruct
{
    public short A;
    public short B;

    public MyStruct(short a, short b)
    {
        A = a;
        B = b;
    }
}

private unsafe byte[] UnsafeStruct(MyStruct myStruct)
{
    byte[] buffer = new byte[4]; // where 4 is the size of the struct
    fixed (byte* ptr = buffer)
    {
        *((MyStruct*)ptr) = myStruct;
    }
    return buffer;
}
濫情▎り 2024-09-02 22:35:51

只是位移位...

buffer[0]=(byte)SomeShort;
buffer[1]=(byte)(SomeShort >> 8);
buffer[2]=(byte)SomeOtherShort;
buffer[3]=(byte)(SomeOtherShort >> 8);

这也意味着您可以完全控制字节序(在本例中为小字节序)

Just bit-shift...

buffer[0]=(byte)SomeShort;
buffer[1]=(byte)(SomeShort >> 8);
buffer[2]=(byte)SomeOtherShort;
buffer[3]=(byte)(SomeOtherShort >> 8);

This also means you are in complete control of the endian-ness (in this case, little-endian)

您的好友蓝忘机已上羡 2024-09-02 22:35:51

您可以使用 Array.Copy 使代码稍微短一些,但是 BitConverter 中没有任何 GetBytes 重载或等效函数将字节直接放入缓冲区。

也许 BinaryWriterMemoryStream 是您想要的吗?

请注意,如果采用您不喜欢的 BitConverter API 约定,则会给您的班级用户带来同样的问题。相反,编写一个接受 BinaryWriter 并将您的类序列化到其中的方法,当您的类嵌入到其他对象中时,这可以很好地扩展。

You can make your code a little shorter by using Array.Copy, but no there isn't any GetBytes overload or equivalent in BitConverter that puts the bytes directly into your buffer.

Maybe BinaryWriter on a MemoryStream is what you want?

Note that by adopting the API conventions of BitConverter which you don't like, you're causing the same problem for users of your class. Instead, write a method which accepts a BinaryWriter and serializes your class into it, this extends nicely when your class is embedded in some other object.

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