BitConverter.GetBytes in place

后端 未结 5 864
-上瘾入骨i
-上瘾入骨i 2021-01-20 05:17

I need to get values in UInt16 and UInt64 as Byte[]. At the moment I am using BitConverter.GetBytes, but this method give

相关标签:
5条回答
  • 2021-01-20 05:37

    It seems that you wish to avoid, for some reason, creating any temporary new arrays. And you also want to avoid unsafe code.

    You could pin the object and then copy to the array.

    public static void ToBytes(ulong value, byte[] array, int offset) 
    {
        GCHandle handle = GCHandle.Alloc(value, GCHandleType.Pinned);
        try
        {
            Marshal.Copy(handle.AddrOfPinnedObject(), array, offset, 8);
        }
        finally
        {
            handle.Free();
        }
    }
    
    0 讨论(0)
  • 2021-01-20 05:42

    BinaryWriter can be a good solution.

    var writer = new BinaryWriter(new MemoryStream(yourbuffer, youroffset, yourbuffer.Length-youroffset));
    writer.Write(someuint64);
    

    It's useful when you need to convert a lot of data into a buffer continuously

    var writer = new BinaryWriter(new MemoryStream(yourbuffer));
    foreach(var value in yourints){
        writer.Write(value);
    }
    

    or when you just want to write to a file, that's the best case to use BinaryWriter.

    var writer = new BinaryWriter(yourFileStream);
    foreach(var value in yourints){
        writer.Write(value);
    }
    
    0 讨论(0)
  • 2021-01-20 05:47

    You can do like this:

    static unsafe void ToBytes(ulong value, byte[] array, int offset)
    {
        fixed (byte* ptr = &array[offset])
            *(ulong*)ptr = value;
    }
    

    Usage:

    byte[] array = new byte[9];
    ToBytes(0x1122334455667788, array, 1);
    

    You can set offset only in bytes.

    If you want managed way to do it:

    static void ToBytes(ulong value, byte[] array, int offset)
    {
        byte[] valueBytes = BitConverter.GetBytes(value);
        Array.Copy(valueBytes, 0, array, offset, valueBytes.Length);
    }
    

    Or you can fill values by yourself:

    static void ToBytes(ulong value, byte[] array, int offset)
    {
        for (int i = 0; i < 8; i++)
        {
            array[offset + i] = (byte)value;
            value >>= 8;
        }
    }
    
    0 讨论(0)
  • 2021-01-20 05:48

    You say you want to avoid creating new arrays and you cannot use unsafe. Either use Ulugbek Umirov's answer with cached arrays (be careful with threading issues) or:

    static void ToBytes(ulong value, byte[] array, int offset) {
     unchecked {
      array[offset + 0] = (byte)(value >> (8*7));
      array[offset + 1] = (byte)(value >> (8*6));
      array[offset + 2] = (byte)(value >> (8*5));
      array[offset + 3] = (byte)(value >> (8*4));
      //...
     }
    }
    
    0 讨论(0)
  • 2021-01-20 05:49

    Now that .NET has added Span<T> support for better working with arrays, unmanaged memory, etc without excess allocations, they've also added System.Buffer.Binary.BinaryPrimitives.

    This works as you would want, e.g. WriteUInt64BigEndian has this signature:

    public static void WriteUInt64BigEndian (Span<byte> destination, ulong value);
    

    which avoids allocating.

    0 讨论(0)
提交回复
热议问题