简体   繁体   English

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

[英]How to Convert Primitive[] to byte[]

For Serialization of Primitive Array, i'am wondering how to convert a Primitive[] to his corresponding byte[]. 对于原始数组的序列化,我想知道如何将Primitive []转换为他对应的byte []。 (ie an int[128] to a byte[512], or a ushort[] to a byte[]...) The destination can be a Memory Stream, a network message, a file, anything. (即int [128]到字节[512],或ushort []到byte [] ...)目标可以是内存流,网络消息,文件,任何东西。 The goal is performance (Serialization & Deserialization time), to be able to write with some streams a byte[] in one shot instead of loop'ing' through all values, or allocate using some converter. 目标是性能(序列化和反序列化时间),能够一次性写入一些字节[],而不是通过所有值循环“,或者使用某些转换器进行分配。

Some already solution explored: 一些已经解决的解决方案:

Regular Loop to write/read 常规循环写入/读取

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

This solution works for Serialization and Deserialization And is like 100 times faster than using Standard System.Runtime.Serialization combined with a BinaryFormater to Serialize/Deserialize a single int, or a couple of them. 此解决方案适用于序列化和反序列化,并且比使用标准System.Runtime.Serialization和BinaryFormater结合使用序列化/反序列化单个int或其中几个快100倍。

But this solution becomes slower if array.Length contains more than 200/300 values (for Int32). 但是如果array.Length包含超过200/300的值(对于Int32),则此解决方案会变慢。

Cast? 投?

Seems C# can't directly cast a Int[] to a byte[], or a bool[] to a byte[]. 似乎C#不能直接将Int []转换为byte [],或者将bool []转换为byte []。

BitConverter.Getbytes() BitConverter.Getbytes()

This solution works, but it allocates a new byte[] at each call of the loop through my int[]. 这个解决方案有效,但它通过我的int []在每次调用循环时分配一个新的byte []。 Performances are of course horrible 表演当然很糟糕

Marshal.Copy Marshal.Copy

Yup, this solution works too, but same problem as previous BitConverter one. 是的,这个解决方案也有效,但与以前的BitConverter问题相同。

C++ hack C ++破解

Because direct cast is not allowed in C#, i tryed some C++ hack after seeing into memory that array length is stored 4 bytes before array data starts 因为在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);
}

and the C# that call: 和调用的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);

I successfully retrieve my int[128] into C++, switch the array length, and affecting the right adress to my 'output' var, but C# is only retrieving a byte[1] as return. 我成功地将我的int [128]检索到C ++中,切换数组长度,并影响我的'output'var的正确地址,但C#只检索一个字节[1]作为返回。 It seems that i can't hack a managed variable like that so easily. 似乎我不能那么容易地破解这样的托管变量。

So i really start to think that all theses casts i want to achieve are just impossible in C# (int[] -> byte[], bool[] -> byte[], double[] -> byte[]...) without Allocating/copying... 所以我真的开始认为我想要实现的所有这些演员在C#(int [] - > byte [],bool [] - > byte [],double [] - > byte [] ...)中是不可能的。没有分配/复制......

What am-i missing? 我错过了什么?

How about using Buffer.BlockCopy ? 使用Buffer.BlockCopy怎么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

Note that BlockCopy is still allocating/copying behind the scenes. 请注意, BlockCopy仍然在后台分配/复制。 I'm fairly sure that this is unavoidable in managed code, and BlockCopy is probably about as good as it gets for this. 我很确定在托管代码中这是不可避免的,而且BlockCopy可能与此相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM