BinaryFormatter spart viel Typinformationen der Lage sein, richtig deserialisieren. Wenn Sie kompakte Serialisierung wollen oder über einen strengen Protokoll comunicate, werden Sie es zu tun haben, explictly wie folgt aus:
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();
}
hier ich jedes Ihrer UInt32 in Byte-Array umwandeln und speichern sie in resultierende Array.
bearbeiten
Es stellte sich heraus dort ist eine andere Art von struct
und Marshal
Zuerst verwenden Sie struct
und markieren es mit Attributen wie das machen:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct MyStruct
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 50)]
public string StringField;
public int IntField;
}
Hier LayoutKind.Sequential
Tells clr zu halten Felder im Speicher in der gleichen Reihenfolge wie die Deklaration. Ohne Pack = 1
können Strukturen mehr Speicher belegen als erforderlich. Wie struct
mit einem short
Feld und einem byte
braucht nur 3 Bytes, aber standardmäßig ist die Größe wird wahrscheinlich 4 (Prozessor verfügt über Anweisungen zum Bearbeiten von einzelnen Byte, 2 Bytes und 4 Bytes, Clr opfert ein Byte pro Instanz von struct, um Menge zu reduzieren der Anweisungen des Maschinencodes um die Hälfte). Jetzt können Sie Marshal
verwenden Bytes zu kopieren:
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);
}
}
Alles funktioniert gut mit einfachen Typen. Für komplexe Typen wie string
müssen Sie MarshalAs
Attribut verwenden und es ist ein bisschen komplizierter (In Beispiel ich sagte Clr zu Marshal String als Array von festen 50 Bytes Größe).
Es muss 16 Bytes ja sein. Irgendwelche Vorschläge wie soll ich den StreamWriter verwenden? –
Ich habe meine Antwort bearbeitet. Das resultierende Byte-Array sollte 16 Byte sein, wenn Sie es so machen, wie ich es vorschlage. Beachten Sie, dass dies nur ein Beispielcode ist. Ich habe es nicht getestet, noch verwendet es eine 'using'-Anweisung, die Sie für Objekte verwenden sollten, die 'IDisposable' wie' MemoryStream' implementieren. Sie könnten dies zu einer Funktion innerhalb Ihres Foo-Objekts machen, so dass Sie foo.Serialize() aufrufen können, um Ihr Byte-Array zu erhalten. –