Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将字节字段整理为字节[]的结构_C#_Struct_Bytearray - Fatal编程技术网

C# 将字节字段整理为字节[]的结构

C# 将字节字段整理为字节[]的结构,c#,struct,bytearray,C#,Struct,Bytearray,嗨,我有一个结构如下 private struct MessageFormat { public byte[] Header; //start of message public byte Fragmentation; //single packet or not public byte Encryption; //encrypted message public byte[] Authentication; //p

嗨,我有一个结构如下

    private struct MessageFormat
    {
        public byte[] Header; //start of message
        public byte Fragmentation; //single packet or not
        public byte Encryption; //encrypted message
        public byte[] Authentication; //password
        public byte[] Flag; //to locate end of auth
        public byte[] Data; //info
        public byte[] Trailer; //end of message
    }

填充所有字段后,是否有一种简便的方法将整个MessageFormat转换为单字节数组[]?

每个字节数组实际上都存储了对字节数组的引用,因此它不是直接的单字节数组


您需要用这些数据构建一个数组。我个人会创建一个方法来实现这一点,创建相应长度的
字节[]
,然后使用它复制到结果数组中。

我已经编写了一个示例代码,它将完全按照您的要求执行。它将反射和
Buffer.BlockCopy
结合在一起,但可以使其性能更高(即预先装箱
format
,避免匿名类型——以及它们在示例中笨拙、冗余的初始化——甚至根本不使用反射和硬编码序列化方法)。请注意,我提供的方法不使用结果缓冲区,而是在分配数组之前计算最终长度

var format = new MessageFormat
{
    //Initialize your format
};
//Gets every instance public field in the type
//Expects it to be either byte, either byte[]
//Extracts value, length and type
var fields = typeof (MessageFormat).GetFields().
    Select(f => f.GetValue(format)).
    Select(v => new
    {
        Value = v,
        Type = v is byte ? typeof (byte) : typeof (byte[]),
        Length = v is byte ? 1 : (v as byte[]).Length
    }).
    ToArray();
//Calculates the resulting array's length
var totalLength = fields.Sum(v => v.Length);
var bytes = new byte[totalLength];
var writingIndex = 0;
foreach (var field in fields)
{
    //If the field is a byte, write at current index,
    //then increment the index
    if (field.Type == typeof (byte))
        bytes[writingIndex++] = (byte) field.Value;
    else
    {
        //Otherwise, use a performant memory copy method
        var source = field.Value as byte[];
        var sourceLength = source.Length;
        Buffer.BlockCopy(source, 0, bytes, writingIndex, sourceLength);
        writingIndex += sourceLength;
    }
}

有很多方法可以做到这一点,但所有这些方法都需要逐字段提取字节

这里有一个:

var msg = new MessageFormat();
var arr = new byte[msg.Header.Length + 1 + 1 + msg.Authentication.Length + msg.Flag.Length + msg.Data.Length + msg.Trailer.Length];
using (var stream = new MemoryStream(arr, 0, arr.Length, true))
{
    stream.Write(msg.Header, 0, msg.Header.Length);
    stream.WriteByte(msg.Fragmentation);
    stream.WriteByte(msg.Encryption);
    stream.Write(msg.Authentication, 0, msg.Authentication.Length);
    stream.Write(msg.Flag, 0, msg.Flag.Length);
    stream.Write(msg.Data, 0, msg.Data.Length);
    stream.Write(msg.Trailer, 0, msg.Trailer.Length);
}

您也可以使用
Buffer.BlockCopy
Array.Copy

尝试查找BitArray类。有一种简便的方法,但您可能不喜欢它。NET framework方式非常担心确保字节[]可以安全地转换回原始对象。不那么方便的方法是BinaryWriter。