2014-09-12 46 views
0

我想将一个结构序列化为磁盘作为原始字节。这是它的(简化)版本。将结构编组为字节数组仅适用于单个字节?

[StructLayout(LayoutKind.Sequential, Pack = 1)] 
public class TestData :BaseStructure 
{ 
    public byte[] bytes = new byte[]{65,66,67}; // this doesn't write ABC as expected 
} 

write函数使用ConvertStructureToBytes方法将其转换为一个字节数组和一个二进制作家然后将其写入。

public void Write(BaseStructure baseStructure) 
    { 
     binaryWriter.Write(ConvertStructureToBytes(baseStructure)); 
    } 

ConvertStructureToBytes部分

public byte[] ConvertStructureToBytes(BaseStructure baseStructure) 
    { 
     int len = Marshal.SizeOf(baseStructure); 
     byte[] arr = new byte[len]; 

     IntPtr ptr = Marshal.AllocHGlobal(len); 
     Marshal.StructureToPtr(baseStructure, ptr,false); 
     Marshal.Copy(ptr, arr, 0, len); 

     Marshal.FreeHGlobal(ptr); 
     return arr; 
    } 

如果我更换字节线

public byte byte = 65; // This now writes an A , as expected 

我已经试过

public byte[] bytes = Encoding.ASCII.GetBytes("ABC"); //doesn't work either 

这可能有事情做与ConvertStructureToBytes函数,它不应该像处理字节数组一样。

我需要做些什么才能成功写出'ABC'?

+0

我编辑了你的标题。请参阅:“[应该在其标题中包含”标签“](http://meta.stackexchange.com/questions/19190/)”,其中的共识是“不,他们不应该”。 – 2014-09-12 21:04:25

+0

什么是BaseStructure?你的'TestData'类继承了它,但是你没有序列化一个'TestData'实例,而是一个'BaseStructure'实例,它不知道'TestData'类中声明的数据。 – Guffa 2014-09-12 21:10:32

回答

3

几个问题。首先你的结构的声明是不正确的,你要在网上的阵列,它不再是一个指针:

[StructLayout(LayoutKind.Sequential, Pack = 1)] 
public class TestData { 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] 
    public byte[] bytes = new byte[] { 65, 66, 67 }; 
} 

然后你ConvertStructureToBytes()方法是不正确的,它只是以往任何时候都元帅BaseStructure。你需要使它通用:

public static byte[] ConvertStructureToBytes<T>(T baseStructure) { 
    // rest the same... 
} 

请注意样的麻烦,你可以进入使用这种方法,它肯定不是元帅数据的通用方式。只有非常特定的类可以通过这种方式进行序列化。那[MarshalAs]属性当然是非常难维护。你也可以使用二进制序列化。

+0

谢谢,这个作品!耶...我实际上是写ISO9660结构的原始字节,涉及的类是目录,文件和路径表,所有预定义和字段,如上述字节将不会改变。所以我认为这个解决方案适用于我:) – 2014-09-12 21:19:24

+0

好吧,一套固定的结构声明是好的。请关闭你的问题。 – 2014-09-12 21:21:14

0

试试这个:

byte[] bytes = Encoding.ASCII.GetBytes("ABC").ToArray(); 

或者,我测试了一下后。也许你的意思是这样的:

bytes = new byte[] { 65, 66, 67 }; 
string test = Encoding.UTF8.GetString(bytes).ToString(); 
1

更改类定义这一点,并尝试:

StructLayout(LayoutKind.Sequential, Pack = 1)] 
public class TestData :BaseStructure 
{ 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] 
    public byte[] bytes = new byte[]{65,66,67}; 
} 
相关问题