2014-09-12 48 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}; 
} 
相關問題