¿Cuál es la diferencia entre Serialization y Marshaling?

Respuestas:

405

Cálculo de referencias y la serialización son vagamente sinónimos en el contexto de la llamada a procedimiento remoto, pero semánticamente diferentes como una cuestión de intención.

En particular, el cálculo de referencias consiste en obtener parámetros de aquí para allá, mientras que la serialización consiste en copiar datos estructurados ao desde una forma primitiva, como un flujo de bytes. En este sentido, la serialización es un medio para realizar el cálculo de referencias, generalmente implementando una semántica de paso por valor.

También es posible ordenar un objeto por referencia, en cuyo caso los datos "en el cable" son simplemente información de ubicación para el objeto original. Sin embargo, dicho objeto aún puede ser susceptible de serialización de valor.

Como @Bill menciona, puede haber metadatos adicionales, como la ubicación de la base del código o incluso el código de implementación del objeto.

Jeffrey Hantin
fuente
3
¿Hay una palabra que significa serializar y deserializar al mismo tiempo? Necesita un nombre para una interfaz con esos métodos.
raffian
1
@raffian, ¿te refieres a una interfaz implementada por el objeto que se somete a serialización y deserialización, o por el objeto responsable de administrar el proceso? Las palabras clave que sugeriría son "Serializable" y "Formatter" respectivamente; decorar con Icambios de mayúsculas, etc., según sea necesario.
Jeffrey Hantin
@JeffreyHantin Un objeto responsable de administrar el proceso es lo que quise decir; Estoy usando ISerializer ahora, pero eso es sólo la mitad derecha :)
raffian
66
@raffian en telecomunicaciones, llamamos a un componente que serializa y deserializa un "SerDes" o "serdes", generalmente se pronuncia sir-dez o sir-deez según la preferencia. Supongo que es similar al "módem" (es decir, "Modulador-Demodulador") en su construcción.
davidA
2
@naki es de toda la industria: si observa las hojas de datos FPGA de alta velocidad, mencionarán la funcionalidad SERDES, aunque todas son bastante modernas, desde la década de 1990. Google NGrams sugiere que se hizo más popular en la década de 1980, aunque encontré una instancia en una hoja de datos de IBM de 1970
davidA
208

Ambos hacen una cosa en común: serializar un objeto. La serialización se utiliza para transferir objetos o almacenarlos. Pero:

  • Serialización: cuando serializa un objeto, solo los datos del miembro dentro de ese objeto se escriben en la secuencia de bytes; no el código que realmente implementa el objeto.
  • Marshalling: Término Marshalling se usa cuando hablamos de pasar objetos a objetos remotos (RMI) . En Marshalling Object se serializa (los datos de los miembros se serializan) + Codebase está adjunto.

Entonces, la serialización es parte de Marshalling.

CodeBase es información que le dice al receptor de Object dónde se puede encontrar la implementación de este objeto. Cualquier programa que piense que podría pasar un objeto a otro programa que no lo haya visto antes debe establecer la base de código, de modo que el receptor pueda saber de dónde descargar el código, si no tiene el código disponible localmente. El receptor, al deserializar el objeto, extraerá la base de código y cargará el código desde esa ubicación.

Nasir Ali
fuente
45
+1 para definir qué significa CodeBase en este contexto
Omar Salem
2
La clasificación sin serialización ocurre. Vea Swing's invokeAndWaity Forms's Invoke, que organizan una llamada síncrona al hilo de la interfaz de usuario sin involucrar la serialización.
Jeffrey Hantin
2
"no el código que realmente implementa el objeto": ¿Significa los métodos de clase? o que significa esto Puede usted explicar por favor.
Vishal Anand
2
¿Qué quiere decir the implementation of this object? ¿Podría dar un ejemplo específico de Serializationy Marshalling?
Simin Jie
La clasificación sin serialización ocurre en algunos contextos, como cuando una llamada de función transfiere el flujo de control entre modelos de subprocesos (por ejemplo, entre un grupo de subprocesos compartido y una biblioteca de subprocesos fijos) dentro de un solo proceso. Es por eso que digo que son vagamente sinónimos en el contexto de RPC .
Jeffrey Hantin
94

Del artículo de Wikipedia de Marshalling (informática) :

El término "mariscal" se considera sinónimo de "serializar" en la biblioteca estándar de Python 1 , pero los términos no son sinónimos en el RFC 2713 relacionado con Java:

Para "ordenar" un objeto significa registrar su estado y su (s) base (s) de código de tal manera que cuando el objeto ordenado está "desarmado", se obtiene una copia del objeto original, posiblemente cargando automáticamente las definiciones de clase del objeto. Puede ordenar cualquier objeto que sea serializable o remoto. La clasificación es como la serialización, excepto que la clasificación también registra las bases de código. La clasificación es diferente de la serialización en que la clasificación trata especialmente los objetos remotos. (RFC 2713)

"Serializar" un objeto significa convertir su estado en una secuencia de bytes de tal manera que la secuencia de bytes se pueda volver a convertir en una copia del objeto.

Por lo tanto, la clasificación también guarda la base de código de un objeto en la secuencia de bytes además de su estado.

Bill el lagarto
fuente
1
Quiere decir que un Objeto, si no está serializado, solo puede tener estado, no habrá ninguna base de código, es decir, no se podrá llamar a ninguna de sus funciones, es solo un tipo de datos estructurado. Y, si se ordena el mismo objeto, ¿tendrá su base de código junto con la estructura y una vez que pueda llamar a sus funciones?
bjan
11
"Codebase" en realidad no significa "Código". De "Cómo funciona Codebase" ( goo.gl/VOM2Ym ) Codebase es, simplemente, cómo los programas que usan la semántica de carga remota de clases de RMI encuentran nuevas clases. Cuando el remitente de un objeto serializa ese objeto para su transmisión a otra JVM, anota la secuencia serializada de bytes con información llamada código base. Esta información le dice al receptor dónde se puede encontrar la implementación de este objeto. La información real almacenada en la anotación de la base de código es una lista de URL de donde se puede descargar el archivo de clase para el objeto necesario.
Giuseppe Bertone
2
@Neurone Esa definición es específica de Jini y RMI. "Codebase" es un término general. en.wikipedia.org/wiki/Codebase
Bill the Lizard
2
@BilltheLizard Sí, pero debido a que estás hablando de cálculo de referencias en Java, es un error decir que la diferencia entre la serialización y la clasificación es "la clasificación guarda el código del objeto además de su estado", y lleva a la pregunta del bjan. Marshalling guarda la "base de código" además del estado del objeto.
Giuseppe Bertone
19

Creo que la principal diferencia es que Marshalling supuestamente también involucra la base de código. En otras palabras, no podrá reunir y desarmar un objeto en una instancia equivalente de estado de una clase diferente. .

La serialización solo significa que puede almacenar el objeto y volver a obtener un estado equivalente, incluso si se trata de una instancia de otra clase.

Dicho esto, suelen ser sinónimos.

Uri
fuente
2
¿Quiere decir que un Objeto, si no está serializado, solo puede tener estado, no habrá ninguna base de código, es decir, no se podrá llamar a ninguna de sus funciones, es solo un tipo de datos estructurado. Y, si se ordena el mismo objeto, ¿tendrá su base de código junto con la estructura y se pueden llamar sus funciones?
bjan
18

Marshaling se refiere a convertir la firma y los parámetros de una función en una sola matriz de bytes. Específicamente para el propósito de RPC.

La serialización se refiere más a menudo a convertir un objeto / árbol de objetos completo en una matriz de bytes. Marshaling serializará los parámetros de los objetos para agregarlos al mensaje y pasarlos a través de la red. * La serialización también se puede utilizar para el almacenamiento en disco. *

H.Gankanda
fuente
11

La clasificación es la regla para decirle al compilador cómo se representarán los datos en otro entorno / sistema; Por ejemplo;

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

como puede ver dos valores de cadena diferentes representados como diferentes tipos de valores.

La serialización solo convertirá el contenido del objeto, no la representación (permanecerá igual) y obedecerá las reglas de serialización (qué exportar o no). Por ejemplo, los valores privados no se serializarán, los valores públicos sí y la estructura del objeto permanecerán igual.

Teoman shipahi
fuente
7

Aquí hay ejemplos más específicos de ambos:

Ejemplo de serialización:

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

En la serialización, los datos se aplanan de una manera que puede almacenarse y desaplanarse más tarde.

Demostración de clasificación:

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

En el cálculo de referencias, los datos no necesariamente deben aplanarse, sino que deben transformarse a otra representación alternativa. todo el casting es de clasificación, pero no todo el casting es de fundición.

Marshaling no requiere una asignación dinámica para participar, sino que también puede ser una transformación entre estructuras. Por ejemplo, puede tener un par, pero la función espera que los elementos primero y segundo del par sean al revés; tu conversión / memcpy de un par a otro no hará el trabajo porque fst y snd se voltearán.

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

El concepto de cálculo de referencias se vuelve especialmente importante cuando comienzas a tratar con uniones etiquetadas de muchos tipos. Por ejemplo, puede que le resulte difícil conseguir que un motor de JavaScript imprima una "cadena c" por usted, pero puede pedirle que imprima una cadena c envuelta por usted. O si desea imprimir una cadena de tiempo de ejecución de JavaScript en un tiempo de ejecución de Lua o Python. Todas son cuerdas, pero a menudo no se llevarán bien sin la organización.

Una molestia que tuve recientemente fue que las matrices JScript marcan a C # como "__ComObject", y no tienen una forma documentada de jugar con este objeto. Puedo encontrar la dirección de dónde está, pero realmente no sé nada más al respecto, por lo que la única forma de averiguarlo realmente es buscarla de cualquier manera posible y espero encontrar información útil al respecto. Por lo tanto, se hace más fácil crear un nuevo objeto con una interfaz más amigable como Scripting.Dictionary, copie los datos del objeto de matriz JScript en él y pase ese objeto a C # en lugar de la matriz predeterminada 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);
        }
    }
}

arriba imprime "__ComObject", que es algo así como un cuadro negro desde el punto de vista de C #.

Otro concepto interesante es que es posible que comprenda cómo escribir código y una computadora que sepa cómo ejecutar instrucciones, por lo que, como programador, está organizando de manera efectiva el concepto de lo que desea que la computadora haga desde su cerebro al programa imagen. Si tuviéramos suficientes comisarios, podríamos pensar en lo que queremos hacer / cambiar, y el programa cambiaría de esa manera sin escribir en el teclado. Entonces, si pudiera tener una manera de almacenar todos los cambios físicos en su cerebro durante los pocos segundos en los que realmente desea escribir un punto y coma, podría reunir esos datos en una señal para imprimir un punto y coma, pero eso es un extremo.

Dmitry
fuente
4

La clasificación suele ser entre procesos relativamente estrechamente asociados; la serialización no necesariamente tiene esa expectativa. Entonces, al ordenar datos entre procesos, por ejemplo, es posible que solo desee enviar una REFERENCIA a datos potencialmente costosos para recuperar, mientras que con la serialización, desearía guardarlo todo, para recrear adecuadamente los objetos cuando se deserializan.

Paul Sonier
fuente
4

Mi comprensión de la clasificación es diferente a las otras respuestas.

Publicación por entregas:

Producir o rehidratar una versión en formato de alambre de un gráfico de objeto utilizando una convención.

Marshalling:

Producir o rehidratar una versión en formato de alambre de un gráfico de objeto utilizando un archivo de mapeo, de modo que los resultados se puedan personalizar. La herramienta puede comenzar adhiriéndose a una convención, pero la diferencia importante es la capacidad de personalizar los resultados.

Primer desarrollo del contrato:

La clasificación es importante dentro del contexto del primer desarrollo del contrato.

  • Es posible realizar cambios en un gráfico de objeto interno, manteniendo la interfaz externa estable a lo largo del tiempo. De esta manera, todos los suscriptores del servicio no tendrán que modificarse para cada cambio trivial.
  • Es posible mapear los resultados en diferentes idiomas. Por ejemplo, de la convención de nombre de propiedad de un idioma ('nombre_propiedad') a otro ('nombreDePropiedad').
Jasper Blues
fuente
1
// ¿Puedo saber más sobre lo que, específicamente, "rehidratar" significa, en esta respuesta aquí, @JasperBlues? Supongo que no es solo para comida de astronauta.
Nathan Basanese
@NathanBasanese acuerdo con esta respuesta - stackoverflow.com/a/6991192/5101816 - definición de (re) hidratante contiene en las siguientes palabras: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

Lo básico primero

Flujo de bytes : el flujo es una secuencia de datos. Flujo de entrada: lee datos de la fuente. Flujo de salida: escribe datos en el destino. Las secuencias de bytes de Java se utilizan para realizar entrada / salida byte a byte (8 bits a la vez). Un flujo de bytes es adecuado para procesar datos sin procesar como archivos binarios. Las secuencias de caracteres Java se utilizan para realizar entradas / salidas de 2 bytes a la vez, ya que los caracteres se almacenan utilizando convenciones Unicode en Java con 2 bytes para cada carácter. La secuencia de caracteres es útil cuando procesamos (leer / escribir) archivos de texto.

RMI (Invocación de método remoto) : una API que proporciona un mecanismo para crear aplicaciones distribuidas en Java. La RMI permite que un objeto invoque métodos en un objeto que se ejecuta en otra JVM.


Tanto la serialización como la clasificación se utilizan libremente como sinónimos. Aquí hay algunas diferencias.

Serialización : los miembros de datos de un objeto se escriben en forma binaria o Byte Stream (y luego se pueden escribir en archivo / memoria / base de datos, etc.). No se puede retener información sobre los tipos de datos una vez que los miembros de datos de objetos se escriben en forma binaria.

ingrese la descripción de la imagen aquí

Marshalling : el objeto se serializa (para byte stream en formato binario) con el tipo de datos + Codebase adjunto y luego se pasa el objeto remoto (RMI) . Marshalling transformará el tipo de datos en una convención de nomenclatura predeterminada para que pueda reconstruirse con respecto al tipo de datos inicial. ingrese la descripción de la imagen aquí

Entonces, la serialización es parte de Marshalling.

CodeBase es información que le dice al receptor de Object dónde se puede encontrar la implementación de este objeto. Cualquier programa que piense que podría pasar un objeto a otro programa que no lo haya visto antes debe establecer la base de código, de modo que el receptor pueda saber de dónde descargar el código, si no tiene el código disponible localmente. El receptor, al deserializar el objeto, extraerá la base de código y cargará el código desde esa ubicación. (Copiado de la respuesta de @Nasir)

La serialización es casi como un estúpido volcado de memoria de la memoria utilizada por el objeto (s), mientras se calcula almacena información sobre tipos de datos personalizados.

En cierto modo, la serialización realiza la clasificación con la implementación del paso por valor porque no se pasa información del tipo de datos, solo se pasa la forma primitiva al flujo de bytes.

La serialización puede tener algunos problemas relacionados con big-endian, small-endian si la secuencia va de un sistema operativo a otro si los diferentes sistemas operativos tienen diferentes medios para representar los mismos datos. Por otro lado, la clasificación está perfectamente bien para migrar entre sistemas operativos porque el resultado es una representación de nivel superior.

Om Sao
fuente
1

Marshaling utiliza el proceso de serialización en realidad, pero la principal diferencia es que en la serialización solo los miembros de datos y el objeto en sí mismo se serializan, no las firmas, sino que en Marshalling Object + code base (su implementación) también se transformará en bytes.

Marshalling es el proceso para convertir objetos java en objetos xml usando JAXB para que pueda usarse en servicios web.

Aman Goel
fuente
0

Piense en ellos como sinónimos, ambos tienen un productor que envía cosas a un consumidor ... Al final, los campos de las instancias se escriben en una secuencia de bytes y el otro extremo se enfrenta al reverso y aparece con las mismas instancias.

NB - java RMI también contiene soporte para transportar clases que faltan del destinatario ...

mP.
fuente