Quelle est la différence entre la sérialisation et le marshaling?

Réponses:

405

Le marshaling et la sérialisation sont vaguement synonymes dans le contexte de l'appel de procédure à distance, mais sémantiquement différents par question d'intention.

En particulier, le marshaling consiste à obtenir des paramètres d'ici à là, tandis que la sérialisation consiste à copier des données structurées vers ou à partir d'une forme primitive telle qu'un flux d'octets. En ce sens, la sérialisation est un moyen d'effectuer le marshaling, implémentant généralement une sémantique passe-par-valeur.

Il est également possible qu'un objet soit marshalé par référence, auquel cas les données "sur le fil" sont simplement des informations de localisation pour l'objet d'origine. Cependant, un tel objet peut toujours se prêter à une sérialisation de valeur.

Comme @Bill le mentionne, il peut y avoir des métadonnées supplémentaires telles que l'emplacement de la base de code ou même le code d'implémentation d'objet.

Jeffrey Hantin
la source
3
Y a-t-il un mot qui signifie sérialiser et désérialiser en même temps? Besoin d'un nom pour une interface avec ces méthodes.
raffian
1
@raffian, voulez-vous dire une interface implémentée par l'objet qui subit la sérialisation et la désérialisation, ou par l'objet responsable de la gestion du processus? Les mots clés que je suggérerais sont respectivement "sérialisable" et "formateur"; décorer avec des Ichangements de majuscule, de capitalisation, etc., si nécessaire.
Jeffrey Hantin
@JeffreyHantin Un objet responsable de la gestion du processus est ce que je voulais dire; J'utilise ISerializer maintenant, mais ce n'est qu'à moitié vrai :)
raffian
6
@raffian dans les télécommunications, nous appelons un composant qui sérialise et désérialise un "SerDes" ou "serdes", généralement prononcé sir-dez ou sir-deez selon votre préférence. Je suppose qu'il est similaire au "modem" (c'est-à-dire "Modulator-Demodulator") dans sa construction.
davidA
2
@naki, c'est à l'échelle de l'industrie - si vous regardez les fiches techniques FPGA haute vitesse, elles mentionneront la fonctionnalité SERDES, bien que celles-ci soient toutes assez modernes, remontant aux années 1990. Google NGrams suggère qu'il est devenu plus populaire dans les années 1980, bien que j'aie trouvé un exemple dans une fiche technique IBM de 1970
davidA
208

Les deux ont une chose en commun: la sérialisation d' un objet. La sérialisation est utilisée pour transférer des objets ou pour les stocker. Mais:

  • Sérialisation: lorsque vous sérialisez un objet, seules les données de membre de cet objet sont écrites dans le flux d'octets; pas le code qui implémente réellement l'objet.
  • Marshalling: Le terme Marshalling est utilisé lorsque nous parlons de passer Object à des objets distants (RMI) . Dans Marshalling, l'objet est sérialisé (les données des membres sont sérialisées) + Codebase est attaché.

La sérialisation fait donc partie du Marshalling.

CodeBase est une information qui indique au récepteur d'Object où l'implémentation de cet objet peut être trouvée. Tout programme qui pense pouvoir passer un objet à un autre programme qui ne l'a peut-être pas vu auparavant doit définir la base de code, afin que le récepteur puisse savoir d'où télécharger le code, s'il n'a pas le code disponible localement. Le récepteur, lors de la désérialisation de l'objet, récupérera la base de code et chargera le code à partir de cet emplacement.

Nasir Ali
la source
45
+1 pour définir ce que signifie CodeBase dans ce contexte
Omar Salem
2
Un marshaling sans sérialisation se produit. Voir Swing invokeAndWaitet Forms Invoke, qui organisent un appel synchrone au thread d'interface utilisateur sans impliquer la sérialisation.
Jeffrey Hantin
2
"pas le code qui implémente réellement l'objet": cela signifie-t-il les méthodes de classe? ou qu'est-ce que cela signifie. Pouvez-vous expliquer.
Vishal Anand
2
Que voulez-vous dire the implementation of this object? Pourriez-vous donner un exemple précis de Serializationet Marshalling?
Simin Jie
Le marshaling sans sérialisation se produit dans certains contextes, comme lorsqu'un appel de fonction transfère le flux de contrôle entre des modèles de thread (par exemple, entre un pool de threads partagé et une bibliothèque de threads à broche unique) au sein d'un même processus. C'est pourquoi je dis qu'ils sont vaguement synonymes dans le contexte de RPC .
Jeffrey Hantin
94

Extrait de l'article Wikipedia sur le Marshalling (informatique) :

Le terme «marshal» est considéré comme synonyme de «sérialiser» dans la bibliothèque standard Python 1 , mais les termes ne sont pas synonymes dans la RFC 2713 relative à Java:

Pour "marshaler" un objet, il faut enregistrer son état et sa ou ses bases de code de telle manière que lorsque l'objet marshallé est "non marshallé", une copie de l'objet d'origine soit obtenue, éventuellement en chargeant automatiquement les définitions de classe de l'objet. Vous pouvez marshaler n'importe quel objet sérialisable ou distant. Le marshaling est comme la sérialisation, sauf que le marshalling enregistre également des bases de code. Le triage est différent de la sérialisation en ce que le triage traite spécialement les objets distants. (RFC 2713)

"Sérialiser" un objet signifie convertir son état en un flux d'octets de telle sorte que le flux d'octets puisse être reconverti en une copie de l'objet.

Ainsi, le marshalling enregistre également la base de code d'un objet dans le flux d'octets en plus de son état.

Bill le lézard
la source
1
Vous voulez dire qu'un objet, s'il n'est pas sérialisé, peut simplement avoir un état, il n'y aura pas de base de code, c'est-à-dire qu'aucune de ses fonctions ne peut être appelée, c'est juste un type de données structurées. Et, si le même objet est organisé, il aura sa base de code avec sa structure et pourra une fois appeler ses fonctions?
bjan
11
"Codebase" ne signifie pas vraiment "Code". De "Comment fonctionne Codebase" ( goo.gl/VOM2Ym ) Codebase est, tout simplement, comment les programmes qui utilisent la sémantique RMI de chargement de classe à distance trouvent de nouvelles classes. Lorsque l'expéditeur d'un objet sérialise cet objet pour le transmettre à une autre machine virtuelle Java, il annote le flux d'octets sérialisé avec des informations appelées la base de code. Ces informations indiquent au récepteur où se trouve l'implémentation de cet objet. Les informations réelles stockées dans l'annotation de la base de code sont une liste d'URL à partir desquelles le fichier de classe de l'objet requis peut être téléchargé.
Giuseppe Bertone
2
@Neurone Cette définition est spécifique à Jini et RMI. "Codebase" est un terme général. en.wikipedia.org/wiki/Codebase
Bill the Lizard
2
@BilltheLizard Oui, mais parce que vous parlez de marshalling en Java, il est faux de dire que la différence entre la sérialisation et le marshalling est que "le marshalling enregistre le code de l'objet en plus de son état", et cela conduit à la question du bjan. Le Marshalling enregistre la "base de code" en plus de l'état de l'objet.
Giuseppe Bertone
19

Je pense que la principale différence est que le Marshalling implique également la base de code. En d'autres termes, vous ne pourrez pas marshaler et démarsaler un objet dans une instance équivalente à l'état d'une classe différente. .

La sérialisation signifie simplement que vous pouvez stocker l'objet et obtenir de nouveau un état équivalent, même s'il s'agit d'une instance d'une autre classe.

Cela étant dit, ce sont généralement des synonymes.

Uri
la source
2
Voulez-vous dire qu'un objet, s'il n'est pas sérialisé, peut simplement avoir un état, il n'y aura pas de base de code, c'est-à-dire qu'aucune de ses fonctions ne peut être appelée, c'est juste un type de données structuré. Et, si le même objet est organisé, il aura sa base de code avec sa structure et on peut appeler ses fonctions?
bjan
18

Marshaling fait référence à la conversion de la signature et des paramètres d'une fonction en un tableau à un octet. Spécifiquement aux fins de RPC.

La sérialisation se réfère le plus souvent à la conversion d'un objet / arbre d'objet entier en un tableau d'octets. Marshaling sérialisera les paramètres d'objet afin de les ajouter au message et de le transmettre à travers le réseau. * La sérialisation peut également être utilisée pour le stockage sur disque. *

H.Gankanda
la source
11

Le marshaling est la règle pour dire au compilateur comment les données seront représentées sur un autre environnement / système; Par exemple;

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

comme vous pouvez voir deux valeurs de chaîne différentes représentées comme des types de valeurs différents.

La sérialisation ne convertira que le contenu de l'objet, pas la représentation (restera la même) et obéira aux règles de sérialisation (quoi exporter ou non). Par exemple, les valeurs privées ne seront pas sérialisées, les valeurs publiques oui et la structure de l'objet restera la même.

Teoman shipahi
la source
7

Voici des exemples plus spécifiques des deux:

Exemple de sérialisation:

#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;
}

Dans la sérialisation, les données sont aplaties d'une manière qui peut être stockée et non aplatie ultérieurement.

Démo de Marshalling:

(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);    
}

Dans le marshaling, les données n'ont pas nécessairement besoin d'être aplaties, mais elles doivent être transformées en une autre représentation alternative. tout casting est marshaling, mais pas tout marshaling est casting.

Le marshaling ne nécessite pas d'allocation dynamique pour être impliqué, il peut également être simplement une transformation entre les structures. Par exemple, vous pouvez avoir une paire, mais la fonction s'attend à ce que les premier et deuxième éléments de la paire soient inversés; vous cast / memcpy une paire à une autre ne fera pas l'affaire car fst et snd seront inversés.

#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;
}

Le concept de marshaling devient particulièrement important lorsque vous commencez à traiter des unions balisées de nombreux types. Par exemple, vous pourriez trouver difficile d'obtenir un moteur JavaScript pour imprimer une "chaîne c" pour vous, mais vous pouvez lui demander d'imprimer une chaîne c enveloppée pour vous. Ou si vous souhaitez imprimer une chaîne à partir de l'exécution JavaScript dans une exécution Lua ou Python. Ce sont toutes des chaînes, mais ne s'entendent souvent pas sans marshaling.

Un ennui que j'ai eu récemment était que les tableaux JScript marshal en C # en tant que «__ComObject», et n'a aucun moyen documenté de jouer avec cet objet. Je peux trouver l'adresse de l'endroit où il se trouve, mais je ne sais vraiment rien d'autre à ce sujet, donc la seule façon de vraiment le comprendre est de le fouiller de toutes les manières possibles et, espérons-le, de trouver des informations utiles à ce sujet. Il devient donc plus facile de créer un nouvel objet avec une interface plus conviviale comme Scripting.Dictionary, de copier les données de l'objet de tableau JScript dans celui-ci et de passer cet objet à C # au lieu du tableau par défaut de JScript.

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);
        }
    }
}

ci-dessus imprime "__ComObject", qui est en quelque sorte une boîte noire du point de vue de C #.

Un autre concept intéressant est que vous pourriez comprendre comment écrire du code et un ordinateur qui sait comment exécuter des instructions, donc en tant que programmeur, vous êtes en train de marshaler efficacement le concept de ce que vous voulez que l'ordinateur fasse de votre cerveau au programme image. Si nous avions suffisamment de bons marshallers, nous pourrions penser à ce que nous voulons faire / changer, et le programme changerait de cette façon sans taper sur le clavier. Donc, si vous pouviez avoir un moyen de stocker tous les changements physiques dans votre cerveau pendant les quelques secondes où vous voulez vraiment écrire un point-virgule, vous pouvez rassembler ces données en un signal pour imprimer un point-virgule, mais c'est un extrême.

Dmitry
la source
4

Le triage se fait généralement entre des processus relativement étroitement associés; la sérialisation n'a pas nécessairement cette attente. Ainsi, lorsque vous rassemblez des données entre des processus, par exemple, vous souhaiterez peut-être simplement envoyer une RÉFÉRENCE à des données potentiellement coûteuses à récupérer, alors qu'avec la sérialisation, vous souhaiterez tout sauvegarder, pour recréer correctement les objets lorsqu'ils seront désérialisés.

Paul Sonier
la source
4

Ma compréhension du marshaling est différente des autres réponses.

Sérialisation:

Pour produire ou réhydrater une version filaire d'un graphe objet à l'aide d'une convention.

Triage:

Pour produire ou réhydrater une version au format filaire d'un graphique d'objet à l'aide d'un fichier de mappage, afin que les résultats puissent être personnalisés. L'outil peut commencer par adhérer à une convention, mais la différence importante est la possibilité de personnaliser les résultats.

Contrat premier développement:

Le triage est important dans le contexte du développement de contrat d'abord.

  • Il est possible d'apporter des modifications à un graphique d'objet interne, tout en maintenant l'interface externe stable dans le temps. De cette façon, tous les abonnés au service n'auront pas à être modifiés pour chaque changement trivial.
  • Il est possible de cartographier les résultats dans différentes langues. Par exemple, de la convention de nom de propriété d'une langue ('nom_propriété') à une autre ('nom_propriété').
Jasper Blues
la source
1
//, Puis-je en savoir plus sur ce que signifie spécifiquement "réhydrater", dans cette réponse ici, @ JasperBlues? Je suppose que ce n'est pas seulement pour la nourriture des astronautes.
Nathan Basanese
@NathanBasanese selon cette réponse - stackoverflow.com/a/6991192/5101816 - la définition de (ré) hydratation contient les mots suivants: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

Basics First

Byte Stream - Stream est une séquence de données. Flux d'entrée - lit les données de la source. Flux de sortie - écrit les données dans la destination. Les flux d'octets Java sont utilisés pour effectuer des octets d'entrée / sortie octet par octet (8 bits à la fois). Un flux d'octets convient au traitement de données brutes comme les fichiers binaires. Les flux de caractères Java sont utilisés pour effectuer 2 octets d'entrée / sortie à la fois, car les caractères sont stockés en utilisant les conventions Unicode en Java avec 2 octets pour chaque caractère. Le flux de caractères est utile lorsque nous traitons (lecture / écriture) des fichiers texte.

RMI (Remote Method Invocation) - une API qui fournit un mécanisme pour créer une application distribuée en java. Le RMI permet à un objet d'appeler des méthodes sur un objet exécuté dans une autre JVM.


La sérialisation et le marshaling sont utilisés comme synonymes. Voici quelques différences.

Sérialisation - Les données membres d'un objet sont écrites sous forme binaire ou Byte Stream (et peuvent ensuite être écrites dans un fichier / mémoire / base de données, etc.). Aucune information sur les types de données ne peut être conservée une fois que les membres de données d'objet sont écrits sous forme binaire.

entrez la description de l'image ici

Marshalling - L'objet est sérialisé (en flux d'octets au format binaire) avec le type de données + la base de code attachée, puis passé l' objet distant (RMI) . Le marshalling transformera le type de données en une convention de dénomination prédéterminée afin qu'il puisse être reconstruit par rapport au type de données initial. entrez la description de l'image ici

La sérialisation fait donc partie du Marshalling.

CodeBase est une information qui indique au récepteur d'Object où l'implémentation de cet objet peut être trouvée. Tout programme qui pense pouvoir passer un objet à un autre programme qui ne l'a peut-être pas vu auparavant doit définir la base de code, afin que le récepteur puisse savoir d'où télécharger le code, s'il n'a pas le code disponible localement. Le récepteur, lors de la désérialisation de l'objet, récupérera la base de code et chargera le code à partir de cet emplacement. (Copié de la réponse @Nasir)

La sérialisation est presque comme un stupide vidage de mémoire de la mémoire utilisée par le ou les objets, tandis que le Marshalling stocke des informations sur les types de données personnalisés.

D'une certaine manière, la sérialisation effectue le marshaling avec implémentation de la valeur de passage car aucune information de type de données n'est transmise, seule la forme primitive est transmise au flux d'octets.

La sérialisation peut avoir des problèmes liés à big-endian, small-endian si le flux passe d'un OS à un autre si les différents OS ont des moyens différents de représenter les mêmes données. En revanche, le marshalling est parfaitement adapté pour migrer entre OS car le résultat est une représentation de plus haut niveau.

Om Sao
la source
1

Marshaling utilise le processus de sérialisation, mais la principale différence est que dans la sérialisation, seuls les membres de données et l'objet lui-même sont sérialisés et non les signatures, mais dans Marshalling Object + code base (son implémentation) sera également transformé en octets.

Le marshaling est le processus de conversion d'un objet Java en objets XML à l'aide de JAXB afin qu'il puisse être utilisé dans les services Web.

Aman Goel
la source
0

Considérez-les comme des synonymes, les deux ont un producteur qui envoie des informations à un consommateur ... À la fin, les champs d'instances sont écrits dans un flux d'octets et l'autre extrémité s'oppose à l'inverse et se retrouve avec les mêmes instances.

NB - java RMI contient également un support pour le transport des classes manquantes du destinataire ...

mP.
la source