如何将Primitive []转换为byte []

时间:2015-06-22 14:48:16

标签: c# binary-serialization

对于原始数组的序列化,我想知道如何将Primitive []转换为他对应的byte []。 (即int [128]到字节[512],或者ushort []到byte [] ......) 目的地可以是记忆流,网络消息,文件,任何东西。 目标是性能(序列化和反序列化时间),能够用一个镜头写一些字节[]而不是循环播放'通过所有值,或使用某些转换器进行分配。

已探索过一些解决方案:

定期循环写入/读取

//array = any int[];
myStreamWriter.WriteInt32(array.Length);
for(int i = 0; i < array.Length; ++i)
   myStreamWriter.WriteInt32(array[i]);

此解决方案适用于序列化和反序列化,并且比使用标准System.Runtime.Serialization和BinaryFormater结合使用序列化/反序列化单个int或其中几个快100倍。

但是如果array.Length包含超过200/300的值(对于Int32),则此解决方案会变慢。

角色吗

似乎C#不能直接将Int []转换为byte [],或者将bool []转换为byte []。

BitConverter.Getbytes()

这个解决方案有效,但它在每次调用循环时通过我的int []分配一个新的byte []。表演当然很糟糕

Marshal.Copy

是的,这个解决方案也有效,但与之前的BitConverter问题相同。

C ++ hack

因为在C#中不允许直接强制转换,所以在看到内存之后尝试了一些C ++ hack,数组长度在数组数据开始之前存储了4个字节

ARRAYCAST_API void Cast(int* input, unsigned char** output)
{
   // get the address of the input (this is a pointer to the data)
   int* count = input;
   // the size of the buffer is located just before the data (4 bytes before as this is an int)
   count--;
   // multiply the number of elements by 4 as an int is 4 bytes
   *count = *count * 4;
   // set the address of the byte array
   *output = (unsigned char*)(input);
}

和调用的C#:

byte[] arrayB = null;
int[] arrayI = new int[128];
for (int i = 0; i < 128; ++i)
   arrayI[i] = i;

// delegate call
fptr(arrayI, out arrayB);

我成功地将我的int [128]检索到C ++中,切换数组长度,并影响正确的地址到我的输出&#39; var,但C#只返回一个byte [1]作为返回。似乎我不能那么容易地破解这样的托管变量。

所以我真的开始认为所有我想要实现的演员阵容在C#(int [] - &gt; byte [],bool [] - &gt; byte [],double [] - &gt; byte中是不可能的[] ...)没有分配/复制......

我错过了什么?

1 个答案:

答案 0 :(得分:4)

如何使用Buffer.BlockCopy

// serialize
var intArray = new[] { 1, 2, 3, 4, 5, 6, 7, 8 };
var byteArray = new byte[intArray.Length * 4];
Buffer.BlockCopy(intArray, 0, byteArray, 0, byteArray.Length);

// deserialize and test
var intArray2 = new int[byteArray.Length / 4];
Buffer.BlockCopy(byteArray, 0, intArray2, 0, byteArray.Length);
Console.WriteLine(intArray.SequenceEqual(intArray2));    // true

请注意,BlockCopy仍在幕后分配/复制。我很确定在托管代码中这是不可避免的,并且BlockCopy可能与此相同。