C# 对象到字节的转换
当我试图将一个对象转换成字节数组时,我得到的是一个wierd数组。 代码如下:C# 对象到字节的转换,c#,.net,conventions,C#,.net,Conventions,当我试图将一个对象转换成字节数组时,我得到的是一个wierd数组。 代码如下: using (MemoryStream ms = new MemoryStream()) { BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(ms, obj); Console.WriteLine(ByteArrayToString(ms.ToArr
using (MemoryStream ms = new MemoryStream())
{
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(ms, obj);
Console.WriteLine(ByteArrayToString(ms.ToArray()));
}
//int obj = 50;
//string ByteArrayToString(byte[] byteArr) the functionality of this method is pretty obvious
结果是:
“00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
有人能解释一下原因吗?:)最佳结果应该只有“32 00 00”。结果中的额外内容将是BinaryFormatter对象。您不仅输出int obj=50,还输出BinaryFormatter中包含的所有内容。结果中的额外内容将是BinaryFormatter对象。您不仅输出int obj=50,还输出BinaryFormatter中包含的所有内容。因为序列化程序需要提供足够的信息来反序列化数据,所以它必须包含一些有关被序列化对象的元数据。具体来说
53 79 73 74 65 6D 2E 49 6E 74 33 32
part代表System.Int32
如果使用及其
Write(Int32)
方法,您将获得所需的效果:内存流将只包含整数中的四个字节。如果不知道您在流中写入了一个Int32
,则无法对其进行反序列化。由于序列化程序需要提供足够的信息来反序列化数据,因此它必须包含一些有关被序列化对象的元数据。具体来说
53 79 73 74 65 6D 2E 49 6E 74 33 32
part代表System.Int32
如果使用及其
Write(Int32)
方法,您将获得所需的效果:内存流将只包含整数中的四个字节。如果不知道您在流中写入了Int32
,则无法对其进行反序列化。您将BinaryFormatter
序列化与对象的内存格式混为一谈。写入流的内容仅仅是BinaryFormatter
的实现细节,不应依赖于任何不使用BinaryFormatter
的进程间通信
如果要查找内置类型的字节表示形式,请使用(对于字符串,请使用适当的)。您正在将
BinaryFormatter
序列化与对象的内存格式混为一谈。写入流的内容仅仅是BinaryFormatter
的实现细节,不应依赖于任何不使用BinaryFormatter
的进程间通信
如果要查找内置类型的字节表示,请使用(对于字符串,请使用适当的)。序列化字节数组同时包含数据本身和类型信息。这就是为什么你得到的信息比你预期的要多。这对于以后的反序列化是必需的。序列化字节数组同时具有数据本身和类型信息。这就是为什么你得到的信息比你预期的要多。这对于以后的反序列化是必需的。序列化过程使用额外的字节来存储有关类型的信息-这是确保序列化数据将反序列化为相同类型的相同对象的唯一方法。 如果您完全确定自己在做什么,并且希望避免任何额外的字节,那么您可以使用自己的序列化并创建格式化程序和序列化程序,这非常复杂。或者,您可以使用编组:
var size = Marshal.SizeOf(your_object);
// Both managed and unmanaged buffers required.
var bytes = new byte[size];
var ptr = Marshal.AllocHGlobal(size);
// Copy object byte-to-byte to unmanaged memory.
Marshal.StructureToPtr(font.LogFont, ptr, false);
// Copy data from unmanaged memory to managed buffer.
Marshal.Copy(ptr, bytes, 0, size);
// Release unmanaged memory.
Marshal.FreeHGlobal(ptr);
和将字节转换为对象:
var bytes = new byte[size];
var ptr = Marshal.AllocHGlobal(size);
Marshal.Copy(bytes, 0, ptr, size);
var your_object = (YourType)Marshal.PtrToStructure(ptr, typeof(YourType));
Marshal.FreeHGlobal(ptr);
在大多数情况下,这是非常缓慢和不安全的,但在不实现序列化和不使用[Serializable]的情况下,将对象严格转换为字节[]是最简单的方法属性。序列化过程使用额外字节存储有关类型的信息-这是确保序列化数据将反序列化为相同类型的相同对象的唯一方法。 如果您完全确定自己在做什么,并且希望避免任何额外的字节,那么您可以使用自己的序列化并创建格式化程序和序列化程序,这非常复杂。或者,您可以使用编组:
var size = Marshal.SizeOf(your_object);
// Both managed and unmanaged buffers required.
var bytes = new byte[size];
var ptr = Marshal.AllocHGlobal(size);
// Copy object byte-to-byte to unmanaged memory.
Marshal.StructureToPtr(font.LogFont, ptr, false);
// Copy data from unmanaged memory to managed buffer.
Marshal.Copy(ptr, bytes, 0, size);
// Release unmanaged memory.
Marshal.FreeHGlobal(ptr);
和将字节转换为对象:
var bytes = new byte[size];
var ptr = Marshal.AllocHGlobal(size);
Marshal.Copy(bytes, 0, ptr, size);
var your_object = (YourType)Marshal.PtrToStructure(ptr, typeof(YourType));
Marshal.FreeHGlobal(ptr);
在大多数情况下,这是非常缓慢和不安全的,但在没有实现序列化和[Serializable]属性的情况下,将对象严格转换为byte[]是最简单的方法。这正是我所期望的。您正在将
MemortyStream
对象而不是整数变量obj
转换为byte
数组。有一个整数
到字节[]
我建议您使用它。我不得不否决这个问题,因为你似乎没有花时间试图弄明白它。@Ramhound:你的解释毫无意义,因为OP显然没有序列化内存流。请参阅。这正是我期望发生的事情。您正在将MemortyStream
对象而不是整数变量obj
转换为byte
数组。有一个整数
到字节[]
我建议您使用它。我不得不否决这个问题,因为你似乎没有花时间试图弄明白它。@Ramhound:你的解释毫无意义,因为OP显然没有序列化内存流。请参阅。-1,否内存流是要写入的内容,而不是要发送到流的内容。是的,说错了,是为了键入BinaryFormatter而分心。为了澄清,额外的内容是二进制序列化的实现细节。它使BinaryFormatter
能够正确地反序列化对象图。实际上,它并不是在对象旁边序列化的BinaryFormatter
实例本身,而是关于对象数量和类型的元数据。-1,不,内存流是要写入的内容,而不是发送到流的内容。对,说错了,意思是要键入BinaryFormatter并分散注意力。为了澄清,额外的内容是二进制序列化的实现细节。它使BinaryFormatter
能够正确地反序列化对象图。事实上,它不是