Was ist der Unterschied zwischen Serialisierung und Marshaling?


Antworten:


404

Marshaling und Serialisierung sind im Kontext eines Remoteprozeduraufrufs lose synonym, unterscheiden sich jedoch absichtlich semantisch.

Beim Marshalling geht es insbesondere darum, Parameter von hier nach dort abzurufen, während bei der Serialisierung strukturierte Daten in oder aus einer primitiven Form wie einem Bytestream kopiert werden. In diesem Sinne ist die Serialisierung ein Mittel zum Durchführen von Marshalling, wobei normalerweise eine Pass-by-Value-Semantik implementiert wird.

Es ist auch möglich, dass ein Objekt als Referenz gemarshallt wird. In diesem Fall sind die Daten "auf dem Draht" einfach Standortinformationen für das ursprüngliche Objekt. Ein solches Objekt kann jedoch weiterhin für eine Wertserialisierung geeignet sein.

Wie @Bill erwähnt, kann es zusätzliche Metadaten geben, z. B. den Speicherort der Codebasis oder sogar den Code für die Objektimplementierung.


3
Gibt es ein Wort, das bedeutet, gleichzeitig zu serialisieren und zu deserialisieren? Benötigen Sie einen Namen für eine Schnittstelle mit diesen Methoden.
Raffian

1
@raffian, meinst du eine Schnittstelle, die von dem Objekt implementiert wird, das einer Serialisierung und Deserialisierung unterzogen wird, oder von dem Objekt, das für die Verwaltung des Prozesses verantwortlich ist? Die Schlüsselwörter, die ich vorschlagen würde, sind "Serializable" bzw. "Formatter"; Dekorieren Sie mit führenden IÄnderungen der Groß- und Kleinschreibung usw. nach Bedarf.
Jeffrey Hantin

@ JeffreyHantin Ein Objekt, das für die Verwaltung des Prozesses verantwortlich ist, habe ich gemeint. Ich benutze jetzt ISerializer, aber das ist nur halb richtig :)
Raffian

6
@raffian in der Telekommunikation nennen wir eine Komponente, die ein "SerDes" oder "Serdes" serialisiert und deserialisiert, normalerweise je nach Präferenz ausgesprochen sir-dez oder sir-deez. Ich nehme an, es ähnelt in seiner Konstruktion "Modem" (dh "Modulator-Demodulator").
DavidA

2
@naki ist branchenweit - wenn Sie sich Hochgeschwindigkeits-FPGA-Datenblätter ansehen, werden sie die SERDES-Funktionalität erwähnen, obwohl diese alle ziemlich modern sind und bis in die 1990er Jahre zurückreichen. Google NGrams schlägt vor, dass es in den 1980er Jahren populärer wurde, obwohl ich eine Instanz in einem IBM-Datenblatt von 1970 gefunden habe
davidA

207

Beide haben eines gemeinsam: Sie serialisieren ein Objekt. Die Serialisierung wird verwendet, um Objekte zu übertragen oder zu speichern. Aber:

  • Serialisierung: Wenn Sie ein Objekt serialisieren, werden nur die Mitgliedsdaten in diesem Objekt in den Bytestream geschrieben. nicht der Code, der das Objekt tatsächlich implementiert.
  • Marshalling: Der Begriff Marshalling wird verwendet, wenn es darum geht, Objekte an entfernte Objekte (RMI) zu übergeben . In Marshalling wird das Objekt serialisiert (Mitgliedsdaten werden serialisiert) + Codebasis wird angehängt.

Serialisierung ist also Teil von Marshalling.

CodeBase ist eine Information, die dem Empfänger von Object mitteilt, wo sich die Implementierung dieses Objekts befindet. Jedes Programm, das glaubt, jemals ein Objekt an ein anderes Programm übergeben zu können, das es möglicherweise noch nicht gesehen hat, muss die Codebasis festlegen, damit der Empfänger weiß, von wo er den Code herunterladen kann, wenn der Code lokal nicht verfügbar ist. Der Empfänger ruft beim Deserialisieren des Objekts die Codebasis ab und lädt den Code von diesem Ort.


45
+1 für die Definition, was CodeBase in diesem Zusammenhang bedeutet
Omar Salem

2
Marshaling ohne Serialisierung findet statt. Siehe Swing's invokeAndWaitund Forms's Invoke, die einen synchronen Aufruf des UI-Threads ohne Serialisierung durchführen.
Jeffrey Hantin

2
"nicht der Code, der das Objekt tatsächlich implementiert": Bedeutet das die Klassenmethoden? oder was bedeutet das? Kannst du bitte Erklären.
Vishal Anand

2
Was meinen Sie the implementation of this object? Könnten Sie ein konkretes Beispiel für Serializationund geben Marshalling?
Simin Jie

Marshalling ohne Serialisierung findet in einigen Kontexten statt, z. B. wenn ein Funktionsaufruf den Kontrollfluss zwischen Threading-Modellen (z. B. zwischen einem gemeinsam genutzten Thread-Pool und einer Single-Pinned-Thread-Bibliothek) innerhalb eines einzelnen Prozesses überträgt. Deshalb sage ich, dass sie im Kontext von RPC auch lose sind .
Jeffrey Hantin

94

Aus dem Wikipedia-Artikel Marshalling (Informatik) :

Der Begriff "Marschall" wird in der Python-Standardbibliothek 1 als Synonym für "serialisieren" angesehen Java-bezogenen RFC 2713 jedoch nicht:

Ein Objekt zu "marshallen" bedeutet, seinen Status und seine Codebasis (en) so aufzuzeichnen, dass beim "Nicht-Marshalling" des kopierten Objekts eine Kopie des ursprünglichen Objekts erhalten wird, möglicherweise durch automatisches Laden der Klassendefinitionen des Objekts. Sie können jedes Objekt marshallen, das serialisierbar oder remote ist. Marshalling ist wie Serialisierung, außer dass Marshalling auch Codebasen aufzeichnet. Marshalling unterscheidet sich von Serialisierung darin, dass Marshalling entfernte Objekte speziell behandelt. (RFC 2713)

Ein Objekt zu "serialisieren" bedeutet, seinen Status so in einen Bytestream umzuwandeln, dass der Bytestream wieder in eine Kopie des Objekts konvertiert werden kann.

Beim Marshalling wird also zusätzlich zu seinem Status auch die Codebasis eines Objekts im Bytestream gespeichert.


1
Sie meinen, ein Objekt, wenn es unserialisiert ist, kann nur einen Status haben, es gibt keine Codebasis, dh keine seiner Funktionen kann aufgerufen werden, es ist nur ein strukturierter Datentyp. Und wenn dasselbe Objekt gemarshallt wird, hat es seine Codebasis zusammen mit der Struktur und kann einmal seine Funktionen aufrufen?
Bjan

11
"Codebasis" bedeutet nicht wirklich "Code". Aus "Funktionsweise von Codebase" ( goo.gl/VOM2Ym ) Codebase beschreibt ganz einfach, wie Programme, die die RMI-Semantik des Ladens von Remoteklassen verwenden, neue Klassen finden. Wenn der Absender eines Objekts dieses Objekt zur Übertragung an eine andere JVM serialisiert, kommentiert er den serialisierten Bytestrom mit Informationen, die als Codebasis bezeichnet werden. Diese Informationen teilen dem Empfänger mit, wo sich die Implementierung dieses Objekts befindet. Die in der Codebasis-Annotation gespeicherten tatsächlichen Informationen sind eine Liste von URLs, von denen die Klassendatei für das benötigte Objekt heruntergeladen werden kann.
Giuseppe Bertone

2
@Neurone Diese Definition ist spezifisch für Jini und RMI. "Codebasis" ist ein allgemeiner Begriff. en.wikipedia.org/wiki/Codebase
Bill the Lizard

2
@BilltheLizard Ja, aber da Sie über Marshalling in Java sprechen, ist es falsch zu sagen, dass der Unterschied zwischen Serialisierung und Marshalling darin besteht, dass Marshalling den Code des Objekts zusätzlich zu seinem Status speichert und dies zur Frage des Bjan führt. Marshalling speichert die "Codebasis" zusätzlich zum Objektstatus.
Giuseppe Bertone

19

Ich denke, dass der Hauptunterschied darin besteht, dass Marshalling angeblich auch die Codebasis betrifft. Mit anderen Worten, Sie könnten ein Objekt nicht in eine zustandsäquivalente Instanz einer anderen Klasse ein- und ausmarschieren. .

Serialisierung bedeutet nur, dass Sie das Objekt speichern und einen äquivalenten Status wiedererlangen können, selbst wenn es sich um eine Instanz einer anderen Klasse handelt.

Davon abgesehen sind sie typischerweise Synonyme.


2
Meinen Sie damit, dass ein Objekt, wenn es unserialisiert ist, nur einen Status haben kann, es keine Codebasis gibt, dh keine seiner Funktionen kann aufgerufen werden kann, es ist nur ein strukturierter Datentyp. Und wenn dasselbe Objekt gemarshallt wird, hat es seine Codebasis zusammen mit der Struktur und man kann seine Funktionen aufrufen?
Bjan

18

Marshaling bezieht sich auf die Konvertierung der Signatur und der Parameter einer Funktion in ein Einzelbyte-Array. Speziell für den Zweck von RPC.

Serialisierung bezieht sich häufiger auf die Konvertierung eines gesamten Objekts / Objektbaums in ein Byte-Array. Marshaling serialisiert Objektparameter, um sie der Nachricht hinzuzufügen und über das Netzwerk zu übertragen. * Die Serialisierung kann auch zur Speicherung auf der Festplatte verwendet werden. *


11

Marshalling ist die Regel, um dem Compiler mitzuteilen, wie die Daten in einer anderen Umgebung / einem anderen System dargestellt werden. Zum Beispiel;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string cFileName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
public string cAlternateFileName;

Wie Sie sehen können, werden zwei verschiedene Zeichenfolgenwerte als unterschiedliche Werttypen dargestellt.

Die Serialisierung konvertiert nur den Objektinhalt, nicht die Darstellung (bleibt gleich) und befolgt die Serialisierungsregeln (was exportiert werden soll oder nicht). Beispielsweise werden private Werte nicht serialisiert, öffentliche Werte yes und die Objektstruktur bleiben gleich.


7

Hier sind spezifischere Beispiele für beides:

Beispiel für die Serialisierung:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

typedef struct {
    char value[11];
} SerializedInt32;

SerializedInt32 SerializeInt32(int32_t x) 
{
    SerializedInt32 result;

    itoa(x, result.value, 10);

    return result;
}

int32_t DeserializeInt32(SerializedInt32 x) 
{
    int32_t result;

    result = atoi(x.value);

    return result;
}

int main(int argc, char **argv)
{    
    int x;   
    SerializedInt32 data;
    int32_t result;

    x = -268435455;

    data = SerializeInt32(x);
    result = DeserializeInt32(data);

    printf("x = %s.\n", data.value);

    return result;
}

Bei der Serialisierung werden Daten auf eine Weise reduziert, die später gespeichert und nicht reduziert werden kann.

Marshalling-Demo:

(MarshalDemoLib.cpp)

#include <iostream>
#include <string>

extern "C"
__declspec(dllexport)
void *StdCoutStdString(void *s)
{
    std::string *str = (std::string *)s;
    std::cout << *str;
}

extern "C"
__declspec(dllexport)
void *MarshalCStringToStdString(char *s)
{
    std::string *str(new std::string(s));

    std::cout << "string was successfully constructed.\n";

    return str;
}

extern "C"
__declspec(dllexport)
void DestroyStdString(void *s)
{
    std::string *str((std::string *)s);
    delete str;

    std::cout << "string was successfully destroyed.\n";
}

(MarshalDemo.c)

#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

int main(int argc, char **argv)
{
    void *myStdString;

    LoadLibrary("MarshalDemoLib");

    myStdString = ((void *(*)(char *))GetProcAddress (
        GetModuleHandleA("MarshalDemoLib"),
        "MarshalCStringToStdString"
    ))("Hello, World!\n");

    ((void (*)(void *))GetProcAddress (
        GetModuleHandleA("MarshalDemoLib"),
        "StdCoutStdString"
    ))(myStdString);

    ((void (*)(void *))GetProcAddress (
        GetModuleHandleA("MarshalDemoLib"),
        "DestroyStdString"
    ))(myStdString);    
}

Beim Marshalling müssen Daten nicht unbedingt reduziert werden, sondern müssen in eine andere alternative Darstellung umgewandelt werden. Alles Casting ist Marshalling, aber nicht alles Marshalling ist Casting.

Das Marshaling erfordert keine dynamische Zuordnung, sondern kann auch nur eine Transformation zwischen Strukturen sein. Beispielsweise könnten Sie ein Paar haben, aber die Funktion erwartet, dass das erste und das zweite Element des Paares umgekehrt sind. Wenn Sie ein Paar auf ein anderes übertragen / memcpy, wird dies nicht erledigt, da fst und snd umgedreht werden.

#include <stdio.h>

typedef struct {
    int fst;
    int snd;
} pair1;

typedef struct {
    int snd;
    int fst;
} pair2;

void pair2_dump(pair2 p)
{
    printf("%d %d\n", p.fst, p.snd);
}

pair2 marshal_pair1_to_pair2(pair1 p)
{
    pair2 result;
    result.fst = p.fst;
    result.snd = p.snd;
    return result;
}

pair1 given = {3, 7};

int main(int argc, char **argv)
{    
    pair2_dump(marshal_pair1_to_pair2(given));

    return 0;
}

Das Konzept des Marshalling wird besonders wichtig, wenn Sie sich mit markierten Gewerkschaften vieler Typen befassen. Beispielsweise könnte es schwierig sein, eine JavaScript-Engine dazu zu bringen, eine "c-Zeichenfolge" für Sie zu drucken, aber Sie können sie bitten, eine umschlossene c-Zeichenfolge für Sie zu drucken. Oder wenn Sie eine Zeichenfolge aus der JavaScript-Laufzeit in einer Lua- oder Python-Laufzeit drucken möchten. Sie sind alle Saiten, kommen aber oft nicht ohne Marshall aus.

Ein Ärger, den ich kürzlich hatte, war, dass JScript-Arrays als "__ComObject" auf C # gemarshallt sind und keine dokumentierte Möglichkeit zum Spielen mit diesem Objekt haben. Ich kann die Adresse finden, an der sie sich befindet, aber ich weiß wirklich nichts anderes darüber. Der einzige Weg, dies wirklich herauszufinden, besteht darin, sie auf jede mögliche Weise zu durchsuchen und hoffentlich nützliche Informationen darüber zu finden. So wird es einfacher, ein neues Objekt mit einer benutzerfreundlicheren Oberfläche wie Scripting.Dictionary zu erstellen, die Daten aus dem JScript-Array-Objekt darin zu kopieren und dieses Objekt anstelle des Standard-Arrays von JScript an C # zu übergeben.

test.js:

var x = new ActiveXObject("Dmitry.YetAnotherTestObject.YetAnotherTestObject");

x.send([1, 2, 3, 4]);

YetAnotherTestObject.cs

using System;
using System.Runtime.InteropServices;

namespace Dmitry.YetAnotherTestObject
{
    [Guid("C612BD9B-74E0-4176-AAB8-C53EB24C2B29"), ComVisible(true)]
    public class YetAnotherTestObject
    {
        public void send(object x)
        {
            System.Console.WriteLine(x.GetType().Name);
        }
    }
}

oben wird "__ComObject" gedruckt, was aus Sicht von C # eine Art Black Box ist.

Ein weiteres interessantes Konzept ist, dass Sie möglicherweise wissen, wie man Code schreibt, und dass ein Computer weiß, wie man Anweisungen ausführt. Als Programmierer stellen Sie also effektiv das Konzept auf, was der Computer von Ihrem Gehirn zum Programm tun soll Bild. Wenn wir gut genug Marshaller hätten, könnten wir uns nur überlegen, was wir tun / ändern wollen, und das Programm würde sich auf diese Weise ändern, ohne auf der Tastatur zu tippen. Wenn Sie also die Möglichkeit haben könnten, alle physischen Veränderungen in Ihrem Gehirn für die wenigen Sekunden zu speichern, in denen Sie wirklich ein Semikolon schreiben möchten, könnten Sie diese Daten in ein Signal umwandeln, um ein Semikolon zu drucken, aber das ist ein Extrem.


4

Marshalling findet normalerweise zwischen relativ eng miteinander verbundenen Prozessen statt. Serialisierung hat nicht unbedingt diese Erwartung. Wenn Sie beispielsweise Daten zwischen Prozessen zusammenstellen, möchten Sie möglicherweise lediglich eine REFERENZ an potenziell teure Daten senden, um sie wiederherzustellen, während Sie bei der Serialisierung alles speichern möchten, um die Objekte beim Deserialisieren ordnungsgemäß neu zu erstellen.


4

Mein Verständnis von Marshalling unterscheidet sich von den anderen Antworten.

Serialisierung:

Erstellen oder Rehydrieren einer Drahtformatversion eines Objektgraphen unter Verwendung einer Konvention.

Marshalling:

Erstellen oder Rehydrieren einer Drahtformatversion eines Objektdiagramms mithilfe einer Zuordnungsdatei, damit die Ergebnisse angepasst werden können. Das Tool beginnt möglicherweise mit der Einhaltung einer Konvention. Der wichtige Unterschied besteht jedoch in der Möglichkeit, die Ergebnisse anzupassen.

Erste Auftragsentwicklung:

Marshalling ist wichtig im Rahmen der ersten Vertragsentwicklung.

  • Es ist möglich, Änderungen an einem internen Objektdiagramm vorzunehmen und gleichzeitig die externe Schnittstelle über die Zeit stabil zu halten. Auf diese Weise müssen nicht alle Dienstabonnenten bei jeder geringfügigen Änderung geändert werden.
  • Es ist möglich, die Ergebnisse in verschiedenen Sprachen abzubilden. Zum Beispiel von der Eigenschaftskonvention einer Sprache ('Eigenschaftsname') zu einer anderen ('Eigenschaftsname').

1
//, Darf ich mehr darüber wissen, was "rehydrieren" in dieser Antwort hier, @JasperBlues, bedeutet? Ich vermute, es ist nicht nur für Astronautenessen.
Nathan Basanese

@ NathanBasanese gemäß dieser Antwort - stackoverflow.com/a/6991192/5101816 - Definition von (Re-) Hydratation enthält in den folgenden Worten:Hydrating an object is taking an object that exists in memory, that doesn't yet contain any domain data ("real" data), and then populating it with domain data (such as from a database, from the network, or from a file system).
pxsx

3

Grundlagen zuerst

Byte Stream - Stream ist eine Folge von Daten. Eingabestream - Liest Daten aus der Quelle. Ausgabestream - schreibt Daten in die Desitnation. Java-Byte-Streams werden verwendet, um die Eingabe / Ausgabe byteweise (jeweils 8 Bit) durchzuführen. Ein Bytestream eignet sich zur Verarbeitung von Rohdaten wie Binärdateien. Java-Zeichenströme werden verwendet, um jeweils 2 Bytes einzugeben / auszugeben, da Zeichen unter Verwendung von Unicode-Konventionen in Java mit 2 Bytes für jedes Zeichen gespeichert werden. Der Zeichenstrom ist nützlich, wenn wir Textdateien verarbeiten (lesen / schreiben).

RMI (Remote Method Invocation) - eine API, die einen Mechanismus zum Erstellen verteilter Anwendungen in Java bereitstellt. Mit dem RMI kann ein Objekt Methoden für ein Objekt aufrufen, das in einer anderen JVM ausgeführt wird.


Sowohl Serialisierung als auch Marshalling werden lose als Synonyme verwendet. Hier sind einige Unterschiede.

Serialisierung - Datenelemente eines Objekts werden in Binärform oder Byte-Stream geschrieben (und können dann in Datei / Speicher / Datenbank usw. geschrieben werden). Sobald Objektdatenelemente in eine binäre Form geschrieben wurden, können keine Informationen über Datentypen beibehalten werden.

Geben Sie hier die Bildbeschreibung ein

Marshalling - Das Objekt wird serialisiert (zum Byte-Stream im Binärformat), wobei Datentyp + Codebasis angehängt und dann Remote Object (RMI) übergeben werden . Durch Marshalling wird der Datentyp in eine vorgegebene Namenskonvention umgewandelt, sodass er in Bezug auf den ursprünglichen Datentyp rekonstruiert werden kann. Geben Sie hier die Bildbeschreibung ein

Serialisierung ist also Teil von Marshalling.

CodeBase ist eine Information, die dem Empfänger von Object mitteilt, wo sich die Implementierung dieses Objekts befindet. Jedes Programm, das glaubt, jemals ein Objekt an ein anderes Programm übergeben zu können, das es möglicherweise noch nicht gesehen hat, muss die Codebasis festlegen, damit der Empfänger weiß, von wo er den Code herunterladen kann, wenn der Code lokal nicht verfügbar ist. Der Empfänger ruft beim Deserialisieren des Objekts die Codebasis ab und lädt den Code von diesem Ort. (Von @Nasir Antwort kopiert)

Die Serialisierung ist fast wie ein dummer Speicherauszug des von den Objekten verwendeten Speichers, während Marshalling Informationen zu benutzerdefinierten Datentypen speichert.

In gewisser Weise führt die Serialisierung das Marshalling mit der Implementierung des Pass-by-Werts durch, da keine Informationen vom Datentyp übergeben werden, sondern nur die primitive Form an den Byte-Stream übergeben wird.

Bei der Serialisierung können einige Probleme im Zusammenhang mit Big-Endian und Small-Endian auftreten, wenn der Stream von einem Betriebssystem zu einem anderen wechselt, wenn die verschiedenen Betriebssysteme unterschiedliche Mittel zur Darstellung derselben Daten haben. Auf der anderen Seite ist Marshalling für die Migration zwischen Betriebssystemen völlig in Ordnung, da das Ergebnis eine Darstellung auf höherer Ebene ist.


1

Marshaling verwendet tatsächlich den Serialisierungsprozess, aber der Hauptunterschied besteht darin, dass bei der Serialisierung nur Datenelemente und das Objekt selbst serialisiert werden, keine Signaturen, sondern in der Marshalling Object + -Codebasis (deren Implementierung) ebenfalls in Bytes umgewandelt werden.

Marshalling ist der Prozess zum Konvertieren von Java-Objekten in XML-Objekte mit JAXB, damit es in Webdiensten verwendet werden kann.


0

Stellen Sie sich diese als Synonyme vor, beide haben einen Produzenten, der Sachen an einen Konsumenten sendet ... Am Ende werden Instanzfelder in einen Bytestream geschrieben, und das andere Ende ist umgekehrt und hat dieselben Instanzen.

NB - Java RMI enthält auch Unterstützung für den Transport von Klassen, die im Empfänger fehlen ...

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.