【问题标题】:C# int64 list to byte array and vice versa casting?C# int64 列表到字节数组,反之亦然?
【发布时间】:2011-05-16 11:09:02
【问题描述】:

请告诉我铸件的优化解决方案:

1)

    public static byte[] ToBytes(List<Int64> list)
    {
        byte[] bytes = null;

        //todo

        return bytes;
    }

2)

    public static List<Int64> ToList(byte[] bytes)
    {
        List<Int64> list = null;

        //todo

        return list;
    }

查看具有最小化复制和/或不安全代码(如果可以实现的话)的版本将非常有帮助。理想情况下,根本不需要复制数据。

更新:

我的问题是关于像 C++ 方式一样的转换:

__int64* ptrInt64 = (__int64*)ptrInt8;

__int8* ptrInt8 = (__int8*)ptrInt64

谢谢你的帮助!!!

【问题讨论】:

  • 您想将每个字节转换为 Int64(反之亦然)还是 8 个字节的块? (Int64 的大小)
  • @BrokenGlass 我需要将每 8 个字节(以块为单位)转换为一个 Int64 值,反之亦然;)
  • 您要的是BitConverter 解决方案还是memcpy 解决方案?
  • @Gabe 如果它是在 C++ 上,我最好要求转换: (__int8*)ptrInt64; (__int64*)ptrInt8;

标签: c# arrays list casting arraylist


【解决方案1】:

编辑,修复了正确的 8 字节转换,在转换回字节数组时效率也不是很高。

    public static List<Int64> ToList(byte[] bytes)
    {
        var list = new List<Int64>();
        for (int i = 0; i < bytes.Length; i += sizeof(Int64))
            list.Add(BitConverter.ToInt64(bytes, i));

        return list;
    }

    public static byte[] ToBytes(List<Int64> list)
    {
      var byteList = list.ConvertAll(new Converter<Int64, byte[]>(Int64Converter));
      List<byte> resultList = new List<byte>();

      byteList.ForEach(x => { resultList.AddRange(x); });
      return resultList.ToArray();
    }

    public static byte[] Int64Converter(Int64 x)
    {
        return BitConverter.GetBytes(x);
    }

【讨论】:

  • 感谢您的帮助和您的代码!我需要将每 8 个字节转换为一个 Int64 值,反之亦然;)
【解决方案2】:

使用Mono.DataConvert。该库具有与大多数原始类型之间的转换器,用于大端、小端和主机顺序字节排序。

【讨论】:

    【解决方案3】:

    CLR 数组知道它们的类型和大小,因此您不能只将一种类型的数组转换为另一种类型。但是,可以对值类型进行不安全的强制转换。例如,这里是BitConverter.GetBytes(long)的来源:

    public static unsafe byte[] GetBytes(long value)
    {
        byte[] buffer = new byte[8];
        fixed (byte* numRef = buffer)
        {
            *((long*) numRef) = value;
        }
        return buffer;
    }
    

    你可以这样写一个 long 列表,像这样:

    public static unsafe byte[] GetBytes(IList<long> value)
    {
        byte[] buffer = new byte[8 * value.Count];
        fixed (byte* numRef = buffer)
        {
            for (int i = 0; i < value.Count; i++)
                *((long*) (numRef + i * 8)) = value[i];
        }
        return buffer;
    }
    

    当然,如果这就是你想要的方式,那么朝相反的方向走很容易。

    【讨论】:

    • 请注意,这始终转换为/从主机字节顺序转换。如果您使用这些函数来序列化数据或以其他方式打包数据以在计算机之间传输,则应选择特定的字节顺序(大端或小端)并专门使用它。否则,当您的软件在具有相反字节顺序的平台上运行时,您将遇到麻烦。
    • cdhowie:您对字节顺序的看法是绝对正确的,但是 OP 询问的是如何转换数组,这意味着他只关心主机的字节顺序。
    猜你喜欢
    • 2010-11-10
    • 1970-01-01
    • 2019-02-14
    • 1970-01-01
    • 2014-04-16
    • 1970-01-01
    • 2015-02-16
    • 2011-07-02
    • 2016-03-08
    相关资源
    最近更新 更多