Ich schreibe einen Prototyp einer TCP-Verbindung und habe Probleme beim Homogenisieren der zu sendenden Daten.
Im Moment sende ich nur Zeichenfolgen, aber in Zukunft möchten wir in der Lage sein, jedes Objekt zu senden.
Der Code ist im Moment recht einfach, da ich dachte, alles könnte in ein Byte-Array umgewandelt werden:
void SendData(object headerObject, object bodyObject)
{
byte[] header = (byte[])headerObject; //strings at runtime,
byte[] body = (byte[])bodyObject; //invalid cast exception
// Unable to cast object of type 'System.String' to type 'System.Byte[]'.
...
}
Dies ist natürlich leicht genug mit einem zu lösen
if( state.headerObject is System.String ){...}
Das Problem ist, wenn ich es so mache, muss ich nach JEDEM Objekttyp suchen, der zur Laufzeit nicht in ein Byte [] umgewandelt werden kann.
Da ich nicht jedes Objekt kenne, das zur Laufzeit nicht in ein Byte [] umgewandelt werden kann, ist dies wirklich keine Option.
Wie konvertiert man ein Objekt überhaupt in ein Byte-Array in C # .NET 4.0?
FileStream
oder ein Objekt, das ein solches Handle kapselt).Antworten:
Verwenden Sie die
BinaryFormatter
:Beachten Sie, dass
obj
alle darin enthaltenen Eigenschaften / Felderobj
(und so weiter für alle ihre Eigenschaften / Felder) mit demSerializable
Attribut versehen werden müssen, damit dies erfolgreich serialisiert werden kann.quelle
using
Block zu packen , da dadurch der verwendete interne Puffer eifrig freigegeben wird.Überprüfen Sie diesen Artikel: http://www.morgantechspace.com/2013/08/convert-object-to-byte-array-and-vice.html
Verwenden Sie den folgenden Code
quelle
MemorySteam
sollte der in einenusing
Block eingeschlossen werden.Wie andere bereits gesagt haben, können Sie die binäre Serialisierung verwenden, diese kann jedoch zusätzliche Bytes erzeugen oder in Objekte mit nicht genau denselben Daten deserialisiert werden. Die Verwendung von Reflexion ist dagegen ziemlich kompliziert und sehr langsam. Es gibt eine andere Lösung, mit der Sie Ihre Objekte strikt in Bytes konvertieren können und umgekehrt: Marshalling:
Und um Bytes in Objekt umzuwandeln:
Es ist merklich langsamer und teilweise unsicher, diesen Ansatz für kleine Objekte und Strukturen zu verwenden, die Feld für Feld mit Ihrer eigenen Serialisierung verglichen werden (aufgrund des doppelten Kopierens von / in nicht verwalteten Speicher), aber es ist die einfachste Möglichkeit, Objekte strikt in Byte [] zu konvertieren, ohne die Serialisierung zu implementieren und ohne [Serializable] -Attribut.
quelle
StructureToPtr
+Copy
ist langsam? Wie kann es langsamer sein als die Serialisierung? Gibt es eine schnellere Lösung?var bytes = new byte[size];
Was Sie suchen, ist Serialisierung. Für die .Net-Plattform stehen verschiedene Formen der Serialisierung zur Verfügung
byte[]
quelle
Sie können es wie unten Code verwenden.
quelle
Verwenden
Encoding.UTF8.GetBytes
ist schneller als VerwendenMemoryStream
. Hier verwende ich NewtonsoftJson , um das Eingabeobjekt in eine JSON-Zeichenfolge zu konvertieren und dann Bytes von der JSON-Zeichenfolge abzurufen .Benchmark für die Version von @Daniel DiPaolo mit dieser Version
quelle
Kombinierte Lösungen in der Erweiterungsklasse:
quelle
Sie könnten die Verwendung Einbau-Serialisierung - Tool im Rahmen und serialize zu einem Memorystream . Dies ist möglicherweise die einfachste Option, erzeugt jedoch möglicherweise ein größeres Byte [], als für Ihr Szenario unbedingt erforderlich ist.
In diesem Fall können Sie mithilfe der Reflexion die Felder und / oder Eigenschaften des zu serialisierenden Objekts durchlaufen und manuell in den MemoryStream schreiben. Bei Bedarf wird die Serialisierung rekursiv aufgerufen, um nicht triviale Typen zu serialisieren. Diese Methode ist komplexer und benötigt mehr Zeit für die Implementierung, ermöglicht Ihnen jedoch eine wesentlich bessere Kontrolle über den serialisierten Stream.
quelle
Wie wäre es mit so etwas Einfachem?
quelle
Ich würde lieber den Ausdruck "Serialisierung" als "Umwandlung in Bytes" verwenden. Das Serialisieren eines Objekts bedeutet, dass es in ein Byte-Array (oder XML oder etwas anderes) konvertiert wird, das auf der Remote-Box zum Rekonstruieren des Objekts verwendet werden kann. In .NET markiert das
Serializable
Attribut Typen, deren Objekte serialisiert werden können.quelle
Alternative Möglichkeit, ein Objekt in ein Byte-Array zu konvertieren:
quelle
Eine zusätzliche Implementierung, die Newtonsoft.Json- Binär-JSON verwendet und nicht erfordert, dass alles mit dem Attribut [Serializable] markiert wird. Der einzige Nachteil besteht darin, dass ein Objekt in eine anonyme Klasse eingeschlossen werden muss, sodass sich das mit der binären Serialisierung erhaltene Byte-Array von diesem unterscheiden kann.
Anonyme Klasse wird verwendet, da BSON mit einer Klasse oder einem Array beginnen sollte. Ich habe nicht versucht, Byte [] zurück zum Objekt zu deserialisieren und bin mir nicht sicher, ob es funktioniert, habe aber die Konvertierungsgeschwindigkeit in Byte [] getestet und es erfüllt meine Anforderungen vollständig.
quelle
Wie wäre es mit Serialisierung? Schauen Sie hier .
quelle