首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将Primitive[]转换为byte[]

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

Stack Overflow用户
提问于 2015-06-22 14:48:15
回答 1查看 1.1K关注 0票数 4

对于原语数组的序列化,我想知道如何将Primitive[]转换为相应的byte[]。( int128 to a byte512,ushort[] to a byte[].)目标可以是一个内存流,一个网络消息,一个文件,任何东西。其目标是性能(序列化和反序列化时间),能够一次编写一个byte[]流,而不是循环所有值,或者使用某种转换器进行分配。

一些已经探讨过的解决办法:

规则循环以写入/读取

代码语言:javascript
复制
//array = any int[];
myStreamWriter.WriteInt32(array.Length);
for(int i = 0; i < array.Length; ++i)
   myStreamWriter.WriteInt32(array[i]);

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

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

Cast?

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

BitConverter.Getbytes()

这个解决方案可以工作,但是它通过我的byte[]在循环的每个调用中分配一个新的int[]。当然,表演是可怕的

Marshal.Copy

是的,这个解决方案也能工作,但与以前的BitConverter解决方案相同。

C++ hack

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

代码语言:javascript
复制
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#则呼吁:

代码语言:javascript
复制
byte[] arrayB = null;
int[] arrayI = new int[128];
for (int i = 0; i < 128; ++i)
   arrayI[i] = i;

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

我成功地将我的int128检索到C++中,切换数组长度,并影响到我的'output‘var的右入口,但是C#只是作为返回检索byte1。看来我不可能那么容易地黑掉这样的托管变量。

因此,我开始认为,我想要实现的所有这些类型在C# (int[] -> byte[],bool[] -> byte[],double[] -> byte[].)中是不可能的。没有分配/复制..。

我错过了什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-06-22 15:15:07

使用Buffer.BlockCopy怎么样?

代码语言:javascript
复制
// 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可能在这方面得到了很好的效果。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30983019

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档