Qual'è la differenza tra Serialization e Marshaling?


Risposte:


405

Il marshalling e la serializzazione sono vagamente sinonimi nel contesto della chiamata di procedura remota, ma semanticamente diversi in termini di intenti.

In particolare, il marshalling riguarda il trasferimento di parametri da qui a lì, mentre la serializzazione riguarda la copia di dati strutturati da o verso una forma primitiva come un flusso di byte. In questo senso, la serializzazione è un mezzo per eseguire il marshalling, di solito implementando la semantica pass-by-value.

È anche possibile eseguire il marshalling di un oggetto per riferimento, nel qual caso i dati "sul filo" sono semplicemente informazioni sulla posizione dell'oggetto originale. Tuttavia, un tale oggetto potrebbe essere ancora suscettibile di valutare la serializzazione.

Come menziona @Bill, potrebbero esserci metadati aggiuntivi come posizione della base di codice o persino codice di implementazione degli oggetti.


3
C'è una parola che significa serializzare e deserializzare allo stesso tempo? È necessario un nome per un'interfaccia con questi metodi.
Raffian,

1
@raffian, intendi un'interfaccia implementata dall'oggetto che viene sottoposto a serializzazione e deserializzazione o dall'oggetto responsabile della gestione del processo? Le parole chiave che suggerirei sono rispettivamente "Serializable" e "Formatter"; decorare con Icambiamenti iniziali e maiuscoli e così via se necessario.
Jeffrey Hantin,

@JeffreyHantin Intendevo un oggetto responsabile della gestione del processo; Sto usando ISerializer ora, ma è solo metà giusto :)
raffian

6
@raffian nelle telecomunicazioni, chiamiamo un componente che serializza e deserializza un "SerDes" o "serdes", generalmente pronunciato sir-dez o sir-deez a seconda delle preferenze. Suppongo che sia simile a "modem" (cioè "Modulator-Demodulator") nella sua costruzione.
David,

2
@naki è in tutto il settore - se guardi i fogli dati FPGA ad alta velocità, menzioneranno la funzionalità SERDES, sebbene siano tutti abbastanza moderni, risalenti agli anni '90. Google NGrams suggerisce che è diventato più popolare negli anni '80, anche se ho trovato un'istanza in una scheda
tecnica

208

Entrambi fanno una cosa in comune: la serializzazione di un oggetto. La serializzazione viene utilizzata per trasferire oggetti o per memorizzarli. Ma:

  • Serializzazione: quando si serializza un oggetto, solo i dati dei membri all'interno di quell'oggetto vengono scritti nel flusso di byte; non il codice che implementa effettivamente l'oggetto.
  • Marshalling: termine Marshalling è usato quando parliamo di passare Object a oggetti remoti (RMI) . In Marshalling Object è serializzato (i dati dei membri sono serializzati) + Codebase è allegato.

Quindi la serializzazione fa parte del marshalling.

CodeBase è un'informazione che dice al destinatario di Object dove è possibile trovare l'implementazione di questo oggetto. Qualsiasi programma che pensa che potrebbe mai passare un oggetto a un altro programma che potrebbe non averlo mai visto prima deve impostare la base di codice, in modo che il destinatario possa sapere da dove scaricare il codice, se non ha il codice disponibile localmente. Il ricevitore, dopo aver deserializzato l'oggetto, recupererà la base di codice da esso e caricherà il codice da quella posizione.


45
+1 per definire cosa significa CodeBase in questo contesto
Omar Salem,

2
Il marshalling senza serializzazione avviene. Vedi Swing invokeAndWaite Forms Invoke, che eseguono il marshalling di una chiamata sincrona al thread dell'interfaccia utente senza comportare la serializzazione.
Jeffrey Hantin,

2
"Non il codice che implementa effettivamente l'oggetto": Significa i metodi di classe? o cosa significa questo. Puoi spiegare per favore.
Vishal Anand,

2
Cosa intendi the implementation of this object? Potresti dare un esempio specifico di Serializatione Marshalling?
Simin Jie,

Il marshalling senza serializzazione si verifica in alcuni contesti, ad esempio quando una chiamata di funzione trasferisce il flusso di controllo tra i modelli di threading (ad esempio, tra un pool di thread condiviso e una libreria a thread singolo) all'interno di un singolo processo. Ecco perché dico che sono vagamente sinonimi nel contesto di RPC .
Jeffrey Hantin,

94

Dal Marshalling (informatica) Articolo Wikipedia:

Il termine "marshal" è considerato sinonimo di "serializzazione" nella libreria standard 1 di Python , ma i termini non sono sinonimi nella RFC 2713 relativa a Java:

"Eseguire il marshalling" di un oggetto significa registrare il suo stato e la (e) base (i) di codice in modo tale che quando l'oggetto con marshalling è "senza marshalling", si ottiene una copia dell'oggetto originale, possibilmente caricando automaticamente le definizioni di classe dell'oggetto. È possibile eseguire il marshalling di qualsiasi oggetto serializzabile o remoto. Il marshalling è come la serializzazione, tranne per il fatto che il marshalling registra anche basi di codice. Il marshalling è diverso dalla serializzazione in quanto il marshalling tratta in modo speciale gli oggetti remoti. (RFC 2713)

"Serializzare" un oggetto significa convertire il suo stato in un flusso di byte in modo tale che il flusso di byte possa essere riconvertito in una copia dell'oggetto.

Pertanto, il marshalling salva anche la base di codice di un oggetto nel flusso di byte oltre al suo stato.


1
Vuoi dire che un oggetto, se non serializzato, può avere solo stato, non ci sarà alcuna base di codice, cioè nessuna delle sue funzioni può essere chiamata, è solo un tipo di dati strutturato. E, se lo stesso oggetto viene eseguito il marshalling, avrà la sua base di codice insieme alla struttura e una volta potrà chiamare le sue funzioni?
bjan

11
"Codebase" in realtà non significa "Codice". Da "Come funziona Codebase" ( goo.gl/VOM2Ym ) Codebase è, semplicemente, come i programmi che usano la semantica di RMI per il caricamento di classi remote trovano nuove classi. Quando il mittente di un oggetto serializza quell'oggetto per la trasmissione a un'altra JVM, annota il flusso serializzato di byte con informazioni chiamate codebase. Queste informazioni indicano al destinatario dove è possibile trovare l'implementazione di questo oggetto. Le informazioni effettive memorizzate nell'annotazione codebase sono un elenco di URL da cui è possibile scaricare il file di classe per l'oggetto necessario.
Giuseppe Bertone,

2
@Neurone Questa definizione è specifica per Jini e RMI. "Codebase" è un termine generale. en.wikipedia.org/wiki/Codebase
Bill the Lizard,

2
@BilltheLizard Sì, ma poiché stai parlando del marshalling in Java, è sbagliato dire che la differenza tra serializzazione e marshalling è "il marshalling salva il codice dell'oggetto oltre al suo stato", e porta alla domanda del bjan. Il marshalling salva il "codebase" oltre allo stato dell'oggetto.
Giuseppe Bertone,

19

Penso che la differenza principale sia che Marshalling coinvolge presumibilmente anche la base di codice. In altre parole, non saresti in grado di eseguire il marshalling e il ripristino di un oggetto in un'istanza equivalente allo stato di una classe diversa. .

La serializzazione significa semplicemente che è possibile archiviare l'oggetto e ottenere nuovamente uno stato equivalente, anche se si tratta di un'istanza di un'altra classe.

Detto questo, in genere sono sinonimi.


2
Vuoi dire che un oggetto, se non serializzato, può avere solo stato, non ci sarà alcuna base di codice, cioè nessuna delle sue funzioni può essere chiamata, è solo un tipo di dati strutturato. E, se lo stesso oggetto viene eseguito il marshalling, avrà la sua base di codice insieme alla struttura e si potranno chiamare le sue funzioni?
bjan

18

Il marshalling si riferisce alla conversione della firma e dei parametri di una funzione in un array a singolo byte. Specificamente ai fini di RPC.

La serializzazione si riferisce più spesso alla conversione di un intero oggetto / albero di oggetti in una matrice di byte. Il marshalling serializzerà i parametri degli oggetti per aggiungerli al messaggio e passarli attraverso la rete. * La serializzazione può essere utilizzata anche per l'archiviazione su disco. *


11

Il marshalling è la regola per dire al compilatore come i dati saranno rappresentati su un altro ambiente / sistema; Per esempio;

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

come puoi vedere due diversi valori di stringa rappresentati come tipi di valore diversi.

La serializzazione convertirà solo il contenuto dell'oggetto, non la rappresentazione (rimarrà la stessa) e obbedirà alle regole di serializzazione (cosa esportare o no). Ad esempio, i valori privati ​​non verranno serializzati, i valori pubblici sì e la struttura degli oggetti rimarrà la stessa.


7

Ecco esempi più specifici di entrambi:

Esempio di serializzazione:

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

Nella serializzazione, i dati vengono appiattiti in un modo che può essere archiviato e non appiattito in seguito.

Demo di smistamento:

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

Nel marshalling, i dati non devono necessariamente essere appiattiti, ma devono essere trasformati in un'altra rappresentazione alternativa. tutto il casting è marshalling, ma non tutto il marshalling è casting.

Il marshalling non richiede l'allocazione dinamica da coinvolgere, può anche essere solo una trasformazione tra strutture. Ad esempio, potresti avere una coppia, ma la funzione si aspetta che il primo e il secondo elemento della coppia siano al contrario; lanciare / memcpy una coppia all'altra non farà il lavoro perché prima e snd verranno capovolti.

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

Il concetto di marshalling diventa particolarmente importante quando inizi a trattare con sindacati etichettati di molti tipi. Ad esempio, potresti trovare difficile ottenere un motore JavaScript per stampare una "stringa c" per te, ma puoi chiedergli di stampare una stringa c incartata per te. O se si desidera stampare una stringa dal runtime JavaScript in un runtime Lua o Python. Sono tutti stringhe, ma spesso non vanno d'accordo senza il marshalling.

Un fastidio che ho avuto di recente è che JScript mette il marshal in C # come "__ComObject" e non ha un modo documentato per giocare con questo oggetto. Posso trovare l'indirizzo di dove si trova, ma in realtà non ne so nient'altro, quindi l'unico modo per capirlo davvero è cercarlo in ogni modo possibile e spero di trovare informazioni utili al riguardo. Quindi diventa più facile creare un nuovo oggetto con un'interfaccia più amichevole come Scripting.Dictionary, copiare i dati dall'oggetto array JScript in esso e passare quell'oggetto a C # invece dell'array predefinito 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);
        }
    }
}

sopra stampa "__ComObject", che è in qualche modo una scatola nera dal punto di vista di C #.

Un altro concetto interessante è che potresti avere la comprensione di come scrivere il codice e un computer che sa come eseguire le istruzioni, quindi come programmatore stai effettivamente facendo il marshalling del concetto di cosa vuoi che il computer faccia dal cervello al programma Immagine. Se avessimo abbastanza marshaller, potremmo solo pensare a cosa vogliamo fare / cambiare, e il programma cambierebbe in quel modo senza digitare sulla tastiera. Quindi, se potessi avere un modo per archiviare tutti i cambiamenti fisici nel tuo cervello per i pochi secondi in cui vuoi davvero scrivere un punto e virgola, potresti trasferire quei dati in un segnale per stampare un punto e virgola, ma questo è un estremo.


4

Lo smistamento è di solito tra processi relativamente strettamente associati; la serializzazione non ha necessariamente questa aspettativa. Pertanto, ad esempio quando si effettuano il marshalling di dati tra processi, è possibile che si desideri semplicemente inviare un RIFERIMENTO a dati potenzialmente costosi da recuperare, mentre con la serializzazione si desidera salvarli tutti, ricreare correttamente gli oggetti quando sono deserializzati.


4

La mia comprensione del marshalling è diversa dalle altre risposte.

serializzazione:

Produrre o reidratare una versione in formato filo di un grafico a oggetti utilizzando una convenzione.

marshalling:

Produrre o reidratare una versione in formato filo di un grafico a oggetti utilizzando un file di mappatura, in modo che i risultati possano essere personalizzati. Lo strumento può iniziare aderendo a una convenzione, ma la differenza importante è la capacità di personalizzare i risultati.

Primo sviluppo del contratto:

Il marshalling è importante nel contesto del primo sviluppo del contratto.

  • È possibile apportare modifiche a un grafico a oggetti interno, mantenendo stabile l'interfaccia esterna nel tempo. In questo modo tutti gli abbonati al servizio non dovranno essere modificati per ogni banale cambiamento.
  • È possibile mappare i risultati in diverse lingue. Ad esempio dalla convenzione sul nome della proprietà di una lingua ('nome_proprietà') in un'altra ('nomeProprietà').

1
//, posso sapere di più su cosa, nello specifico, "reidratare", in questa risposta qui, @JasperBlues? Immagino che non sia solo per il cibo degli astronauti.
Nathan Basanese,

@NathanBasanese secondo questa risposta - stackoverflow.com/a/6991192/5101816 - la definizione di (re) idratazione contiene nelle seguenti parole: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

Nozioni di base prima di tutto

Byte Stream : lo stream è una sequenza di dati. Flusso di input: legge i dati dall'origine. Flusso di output: scrive i dati nella desitnazione. Java Byte Streams sono usati per eseguire input / output byte per byte (8 bit alla volta). Un flusso di byte è adatto per l'elaborazione di dati grezzi come file binari. I flussi di caratteri Java vengono utilizzati per eseguire input / output 2 byte alla volta, poiché i caratteri vengono archiviati utilizzando le convenzioni Unicode in Java con 2 byte per ciascun carattere. Il flusso di caratteri è utile quando elaboriamo (leggi / scrivi) file di testo.

RMI (Richiamo metodo remoto) - un'API che fornisce un meccanismo per creare un'applicazione distribuita in Java. L'RMI consente a un oggetto di invocare metodi su un oggetto in esecuzione in un'altra JVM.


Sia la serializzazione che marshalling sono usati vagamente come sinonimi. Qui ci sono alcune differenze.

Serializzazione : i membri dei dati di un oggetto vengono scritti in forma binaria o Byte Stream (e quindi possono essere scritti in file / memoria / database ecc.). Nessuna informazione sui tipi di dati può essere conservata una volta che i membri dei dati oggetto vengono scritti in forma binaria.

inserisci qui la descrizione dell'immagine

Marshalling - L'oggetto viene serializzato (al flusso di byte in formato binario) con tipo di dati + Codebase collegato e quindi passato a Remote Object (RMI) . Il marshalling trasformerà il tipo di dati in una convenzione di denominazione predeterminata in modo che possa essere ricostruito rispetto al tipo di dati iniziale. inserisci qui la descrizione dell'immagine

Quindi la serializzazione fa parte del marshalling.

CodeBase è un'informazione che dice al destinatario di Object dove è possibile trovare l'implementazione di questo oggetto. Qualsiasi programma che pensa che potrebbe mai passare un oggetto a un altro programma che potrebbe non averlo mai visto prima deve impostare la base di codice, in modo che il destinatario possa sapere da dove scaricare il codice, se non ha il codice disponibile localmente. Il ricevitore, dopo aver deserializzato l'oggetto, recupererà la base di codice da esso e caricherà il codice da quella posizione. (Copiato dalla risposta @Nasir)

La serializzazione è quasi come una stupida discarica di memoria della memoria utilizzata dagli oggetti, mentre Marshalling memorizza informazioni su tipi di dati personalizzati.

In un certo senso, la serializzazione esegue il marshalling con l'implementazione del valore pass-by poiché non vengono trasmesse informazioni sul tipo di dati, solo la forma primitiva viene passata al flusso di byte.

La serializzazione può presentare alcuni problemi relativi a big-endian, small-endian se lo stream passa da un sistema operativo a un altro se il diverso sistema operativo ha mezzi diversi per rappresentare gli stessi dati. D'altra parte, il marshalling è perfetto per migrare tra i sistemi operativi perché il risultato è una rappresentazione di livello superiore.


1

Il marshalling utilizza il processo di serializzazione in realtà, ma la differenza principale è che nella serializzazione solo i membri di dati e l'oggetto stesso ottengono serializzati non firme ma nella Marshalling Object + code base (la sua implementazione) verranno anche trasformati in byte.

Il marshalling è il processo per convertire l'oggetto java in oggetti xml utilizzando JAXB in modo che possa essere utilizzato nei servizi Web.


0

Pensali come sinonimi, entrambi hanno un produttore che invia roba a un consumatore ... Alla fine i campi delle istanze sono scritti in un flusso di byte e l'altra estremità opposta al contrario e procede con le stesse istanze.

NB: java RMI contiene anche il supporto per il trasporto di classi mancanti dal destinatario ...

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.