BinaryFormatter fa risparmiare un sacco di informazioni sul tipo di essere in grado di deserializzare correttamente. Se si desidera che la serializzazione compatta o di comunicare tramite un protocollo rigoroso, si dovrà farlo esplicitamente in questo modo:
public byte[] ToByteArray()
{
List<byte> result = new List<byte>();
result.AddRange(BitConverter.GetBytes(One));
result.AddRange(BitConverter.GetBytes(Two));
result.AddRange(BitConverter.GetBytes(Three));
result.AddRange(BitConverter.GetBytes(Four));
return result.ToArray();
}
qui posso convertire ognuno dei vostri UInt32 in array di byte e riporlo in risultante array.
Modifica
scopre che c'è un altro modo utilizzando struct
e Marshal
Prima di effettuare struct
e segnare con gli attributi del genere:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct MyStruct
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 50)]
public string StringField;
public int IntField;
}
Qui LayoutKind.Sequential
dice a CLR per mantenere i campi in memoria nello stesso ordine della dichiarazione. Senza le strutture Pack = 1
le strutture possono richiedere più memoria del necessario. Come struct
con un campo short
e uno byte
richiede solo 3 byte, ma per impostazione predefinita la dimensione sarà molto probabilmente 4 (il processore ha istruzioni per manipolare un singolo byte, 2 byte e 4 byte, clr sacrifica un byte per ogni istanza della struttura per ridurre l'importo delle istruzioni del codice macchina della metà). Ora è possibile utilizzare per copiare Marshal
byte:
public static byte[] GetBytes<T>(T str)
{
int size = Marshal.SizeOf(str);
var bytes = new byte[size];
IntPtr ptr = Marshal.AllocHGlobal(size);
try
{
Marshal.StructureToPtr(str, ptr, true);
Marshal.Copy(ptr, bytes, 0, size);
return bytes;
}
finally
{
Marshal.FreeHGlobal(ptr);
}
}
Tutto funziona bene con i tipi semplici. Per tipi complessi come string
devi utilizzare l'attributo MarshalAs
e il suo utilizzo è un po 'più complicato (nell'esempio ho detto clr alla stringa di marshall come array di dimensione fissa di 50 byte).
Deve essere 16 byte sì. Qualche suggerimento come dovrei usare lo StreamWriter ?? –
Ho modificato la mia risposta. La matrice di byte risultante dovrebbe essere di 16 byte se lo si fa nel modo che suggerisco. Si noti che questo è solo codice di esempio. Non l'ho testato, né usa un'istruzione 'using' che dovresti usare per oggetti che implementano' IDisposable' come 'MemoryStream'. Potresti decidere di farne una funzione all'interno dell'oggetto Foo, quindi puoi chiamare foo.Serialize() per ottenere il tuo array di byte. –