Qual é a diferença entre Serialization e Marshaling?

Respostas:

405

Marshaling e serialização são vagamente sinônimos no contexto da chamada de procedimento remoto, mas semanticamente diferentes por uma questão de intenção.

Em particular, empacotamento é obter parâmetros daqui para lá, enquanto serialização envolve copiar dados estruturados para ou de uma forma primitiva, como um fluxo de bytes. Nesse sentido, a serialização é um meio de realizar empacotamento, geralmente implementando a semântica de passagem por valor.

Também é possível que um objeto seja empacotado por referência; nesse caso, os dados "no fio" são simplesmente informações de localização do objeto original. No entanto, esse objeto ainda pode ser passível de valorizar a serialização.

Como o @Bill menciona, pode haver metadados adicionais, como localização da base de código ou mesmo código de implementação de objeto.

Jeffrey Hantin
fonte
3
Existe uma palavra que significa serializar e desserializar ao mesmo tempo? Precisa de um nome para uma interface com esses métodos.
raffian
1
@raffian, você quer dizer uma interface implementada pelo objeto que passa por serialização e desserialização ou pelo objeto responsável pelo gerenciamento do processo? As palavras-chave que eu sugeriria são "Serializable" e "Formatter", respectivamente; decore com as principais Imudanças de capitalização e assim por diante, conforme necessário.
21414 Jeffrey Hantin
@JeffreyHantin Um objeto responsável por gerenciar o processo é o que eu quis dizer; Estou usando ISerializer agora, mas isso é apenas metade direita :)
raffian
6
@raffian nas telecomunicações, chamamos um componente que serializa e desserializa um "SerDes" ou "serdes", geralmente pronunciado sir-dez ou sir-deez, dependendo da preferência. Suponho que seja semelhante ao "modem" (isto é, "Modulador-Demodulador") em sua construção.
Davida
2
@naki é de âmbito industrial - se você olhar para as folhas de dados FPGA de alta velocidade, elas mencionarão a funcionalidade SERDES, embora todas sejam bastante modernas, desde a década de 1990. Google NGrams sugere que se tornou mais popular na década de 1980, apesar de eu não encontrar uma instância em um IBM folha de dados a partir de 1970
Davida
208

Ambos fazem uma coisa em comum: serializar um objeto. A serialização é usada para transferir objetos ou armazená-los. Mas:

  • Serialização: quando você serializa um objeto, apenas os dados do membro nesse objeto são gravados no fluxo de bytes; não o código que realmente implementa o objeto.
  • Marshalling: O termo Marshalling é usado quando falamos em passar Object para objetos remotos (RMI) . No Marshalling, o objeto é serializado (os dados do membro são serializados) + o Codebase é anexado.

Portanto, a serialização faz parte do Marshalling.

CodeBase é uma informação que informa ao receptor do Object onde a implementação desse objeto pode ser encontrada. Qualquer programa que pense que pode passar um objeto para outro programa que talvez nunca o tenha visto antes deve definir a base de código, para que o receptor possa saber de onde baixar o código, se não tiver o código disponível localmente. O receptor, ao desserializar o objeto, buscará a base de código e carregará o código nesse local.

Nasir Ali
fonte
45
+1 para definir o código base significa, neste contexto
Omar Salem
2
Marshaling sem serialização acontece. Consulte Swing invokeAndWaite Forms Invoke, que organizam uma chamada síncrona para o thread da interface do usuário sem envolver serialização.
Jeffrey Hantin
2
"não o código que realmente implementa o objeto": significa os métodos de classe? ou o que isso significa? Você pode explicar, por favor.
Vishal Anand
2
Como assim the implementation of this object? Você poderia dar um exemplo específico de Serializatione Marshalling?
precisa saber é o seguinte
O Marshalling sem serialização ocorre em alguns contextos, como quando uma chamada de função transfere o fluxo de controle entre modelos de encadeamento (por exemplo, entre um conjunto de encadeamentos compartilhados e uma biblioteca de encadeamentos com pinos únicos) em um único processo. É por isso que digo que eles são sinônimo de liberdade no contexto da RPC .
Jeffrey Hantin 10/09/19
94

Do artigo da Wikipedia sobre Marshalling (ciência da computação) :

O termo "marechal" é considerado sinônimo de "serializar" na biblioteca padrão do Python 1 , mas os termos não são sinônimos no RFC 2713 relacionado ao Java:

Para "empacotar" um objeto significa registrar seu estado e sua (s) base (s) de código de tal maneira que quando o objeto empacotado é "não empacotado", é obtida uma cópia do objeto original, possivelmente carregando automaticamente as definições de classe do objeto. Você pode empacotar qualquer objeto que seja serializável ou remoto. Marshalling é como serialização, exceto marshalling também registra bases de código. O Marshalling é diferente da serialização, pois ele trata especialmente objetos remotos. (RFC 2713)

"Serializar" um objeto significa converter seu estado em um fluxo de bytes, de modo que o fluxo de bytes possa ser convertido novamente em uma cópia do objeto.

Portanto, o empacotamento também salva a base de código de um objeto no fluxo de bytes, além de seu estado.

Bill the Lizard
fonte
1
Você quer dizer que um Objeto, se não serializado, pode apenas ter estado, não haverá nenhuma base de código, ou seja, nenhuma de suas funções pode ser chamada, é apenas um tipo de dados estruturado. E, se o mesmo objeto for empacotado, ele terá sua base de código junto com a estrutura e poderá chamar suas funções?
bjan
11
"Codebase" não significa realmente "código". Em "How Codebase Works" ( goo.gl/VOM2Ym ), o Codebase é, simplesmente, como os programas que usam a semântica da RMI para o carregamento remoto de classes encontram novas classes. Quando o remetente de um objeto serializa esse objeto para transmissão para outra JVM, ele anota o fluxo de bytes serializado com informações chamadas de base de código. Esta informação informa ao receptor onde a implementação deste objeto pode ser encontrada. As informações reais armazenadas na anotação da base de código são uma lista de URLs a partir das quais o arquivo de classe para o objeto necessário pode ser baixado.
Giuseppe Bertone
2
@Neurone Essa definição é específica para Jini e RMI. "Base de código" é um termo geral. en.wikipedia.org/wiki/Codebase
Bill the Lizard
2
@BilltheLizard Sim, mas porque você está falando sobre marshalling em Java, é errado dizer que a diferença entre serialização e marshalling é "marshalling salva o código do objeto além de seu estado", e isso leva à pergunta do bjan. O Marshalling salva a "base de código" além do estado do objeto.
Giuseppe Bertone
19

Eu acho que a principal diferença é que Marshalling supostamente também envolve a base de código. Em outras palavras, você não seria capaz de organizar e desmarcar um objeto em uma instância equivalente ao estado de uma classe diferente. .

Serialização significa apenas que você pode armazenar o objeto e obter um estado equivalente, mesmo que seja uma instância de outra classe.

Dito isto, eles são tipicamente sinônimos.

Uri
fonte
2
Você quer dizer que um Objeto, se não serializado, pode apenas ter estado, não haverá nenhuma base de código, ou seja, nenhuma de suas funções pode ser chamada, é apenas um tipo de dados estruturado. E, se o mesmo objeto for empacotado, ele terá sua base de código juntamente com a estrutura e poderá-se chamar suas funções?
bjan
18

Marshaling refere-se à conversão da assinatura e dos parâmetros de uma função em uma matriz de byte único. Especificamente para o propósito de RPC.

A serialização geralmente se refere à conversão de uma árvore inteira de objetos / objetos em uma matriz de bytes. O Marshaling serializa os parâmetros do objeto para adicioná-los à mensagem e transmiti-los pela rede. A serialização também pode ser usada para armazenamento em disco.

H.Gankanda
fonte
11

Marshalling é a regra para informar ao compilador como os dados serão representados em outro ambiente / sistema; Por exemplo;

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

como você pode ver dois valores de sequência diferentes representados como tipos de valores diferentes.

A serialização converterá apenas o conteúdo do objeto, não a representação (permanecerá igual) e obedecerá às regras de serialização (o que exportar ou não). Por exemplo, os valores privados não serão serializados, os valores públicos yes e a estrutura do objeto permanecerá a mesma.

Teoman shipahi
fonte
7

Aqui estão exemplos mais específicos de ambos:

Exemplo de serialização:

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

Na serialização, os dados são achatados de uma maneira que pode ser armazenada e não achatada posteriormente.

Demonstração 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);    
}

No empacotamento, os dados não precisam necessariamente ser achatados, mas precisam ser transformados em outra representação alternativa. todo casting é empacotado, mas nem todo empacotamento está empacotado.

Marshaling não requer alocação dinâmica para ser envolvido, mas também pode ser apenas uma transformação entre estruturas. Por exemplo, você pode ter um par, mas a função espera que o primeiro e o segundo elementos do par sejam inversamente opostos; você converter / memorizar um par para outro não fará o trabalho porque fst e snd serão invertidos.

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

O conceito de empacotamento se torna especialmente importante quando você começa a lidar com uniões marcadas de vários tipos. Por exemplo, você pode achar difícil conseguir que um mecanismo JavaScript imprima uma "string c" para você, mas você pode solicitar que imprima uma string c quebrada para você. Ou se você deseja imprimir uma sequência do tempo de execução JavaScript em um tempo de execução Lua ou Python. São todas cordas, mas muitas vezes não se dão bem sem empacotar.

Um aborrecimento que tive recentemente foi o fato de o JScript arrumar um empacotador para C # como "__ComObject" e não ter uma maneira documentada de brincar com esse objeto. Eu posso encontrar o endereço de onde ele está, mas eu realmente não sei mais nada sobre isso, então a única maneira de realmente descobrir isso é cutucando-o de qualquer maneira possível e, esperançosamente, encontrar informações úteis sobre ele. Portanto, fica mais fácil criar um novo objeto com uma interface mais amigável como Scripting.Dictionary, copiar os dados do objeto da matriz JScript para ele e passar esse objeto para C # em vez da matriz padrão do 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);
        }
    }
}

acima imprime "__ComObject", que é uma espécie de caixa preta do ponto de vista do C #.

Outro conceito interessante é que você pode entender como escrever código e um computador que sabe executar instruções; portanto, como programador, você está efetivamente organizando o conceito do que deseja que o computador faça do seu cérebro para o programa imagem. Se tivéssemos marshallers bons o suficiente, poderíamos apenas pensar no que queremos fazer / mudar, e o programa mudaria dessa maneira sem digitar no teclado. Portanto, se você pudesse ter uma maneira de armazenar todas as alterações físicas em seu cérebro por alguns segundos em que realmente deseja escrever um ponto e vírgula, poderá reunir esses dados em um sinal para imprimir um ponto e vírgula, mas isso é extremo.

Dmitry
fonte
4

Marshalling é geralmente entre processos relativamente estreitamente associados; a serialização não tem necessariamente essa expectativa. Portanto, ao organizar dados entre processos, por exemplo, você pode simplesmente enviar uma REFERÊNCIA para dados potencialmente caros para recuperar, enquanto que com a serialização, você deseja salvar tudo, para recriar adequadamente o (s) objeto (s) quando desserializados.

Paul Sonier
fonte
4

Meu entendimento de marshalling é diferente das outras respostas.

Serialização:

Produzir ou reidratar uma versão em formato de fio de um gráfico de objeto utilizando uma convenção.

Marshalling:

Produzir ou reidratar uma versão em formato de fio de um gráfico de objeto utilizando um arquivo de mapeamento, para que os resultados possam ser personalizados. A ferramenta pode começar aderindo a uma convenção, mas a diferença importante é a capacidade de personalizar resultados.

Primeiro desenvolvimento do contrato:

A Marshalling é importante dentro do contexto do primeiro desenvolvimento do contrato.

  • É possível fazer alterações em um gráfico interno de objetos, mantendo a interface externa estável ao longo do tempo. Dessa forma, todos os assinantes do serviço não precisarão ser modificados para cada alteração trivial.
  • É possível mapear os resultados em diferentes idiomas. Por exemplo, da convenção de nome de propriedade de um idioma ('property_name') para outro ('propertyName').
Jasper Blues
fonte
1
//, posso saber mais sobre o que, especificamente, "reidratar" significa, nesta resposta aqui, @JasperBlues? Acho que não é só para comida de astronauta.
Nathan Basanese
@NathanBasanese de acordo com esta resposta - stackoverflow.com/a/6991192/5101816 - a definição de (re) hydrating contém nas seguintes palavras: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

Noções básicas primeiro

Fluxo de bytes - Stream é a sequência de dados. Fluxo de entrada - lê dados da fonte. Fluxo de saída - grava dados na dessitnação. Os fluxos de bytes de Java são usados ​​para executar bytes de entrada / saída por byte (8 bits por vez). Um fluxo de bytes é adequado para processar dados brutos, como arquivos binários. O Java Character Streams é usado para executar entrada / saída 2 bytes por vez, porque os caracteres são armazenados usando convenções Unicode em Java com 2 bytes para cada caractere. O fluxo de caracteres é útil quando processamos (leitura / gravação) arquivos de texto.

RMI (Remote Method Invocation) - uma API que fornece um mecanismo para criar aplicativos distribuídos em java. A RMI permite que um objeto chame métodos em um objeto em execução em outra JVM.


Ambos serialização e Marshalling são vagamente usados como sinônimos. Aqui estão algumas diferenças.

Serialização - Os membros de dados de um objeto são gravados no formato binário ou no Byte Stream (e podem ser gravados no arquivo / memória / banco de dados etc). Nenhuma informação sobre tipos de dados pode ser mantida depois que os membros de dados do objeto são gravados no formato binário.

insira a descrição da imagem aqui

Marshalling - O objeto é serializado (para fluxo de bytes em formato binário) com o tipo de dados + Codebase anexado e passado o Remote Object (RMI) . O Marshalling transformará o tipo de dados em uma convenção de nomenclatura predeterminada, para que possa ser reconstruído com relação ao tipo de dados inicial. insira a descrição da imagem aqui

Portanto, a serialização faz parte do Marshalling.

CodeBase é uma informação que informa ao receptor do Object onde a implementação desse objeto pode ser encontrada. Qualquer programa que pense que pode passar um objeto para outro programa que talvez nunca o tenha visto antes deve definir a base de código, para que o receptor possa saber de onde baixar o código, se não tiver o código disponível localmente. O receptor, ao desserializar o objeto, buscará a base de código e carregará o código nesse local. (Copiado da resposta @Nasir)

A serialização é quase como um estúpido despejo de memória da memória usada pelo (s) objeto (s), enquanto Marshalling armazena informações sobre tipos de dados personalizados.

De certa forma, a serialização executa o empacotamento com implementação de passagem por valor, porque nenhuma informação do tipo de dados é passada, apenas a forma primitiva é passada para o fluxo de bytes.

A serialização pode ter alguns problemas relacionados a big endian e small endian se o fluxo estiver indo de um sistema operacional para outro se o sistema operacional diferente tiver meios diferentes de representar os mesmos dados. Por outro lado, o empacotamento é perfeitamente adequado para migrar entre o SO, porque o resultado é uma representação de nível superior.

Om Sao
fonte
1

O Marshaling usa o processo de serialização, na verdade, mas a principal diferença é que, na serialização, apenas os membros de dados e o próprio objeto são serializados, não assinaturas, mas no Marshalling Object + a base de código (sua implementação) também será transformada em bytes.

Marshalling é o processo para converter objetos java em objetos xml usando JAXB para que eles possam ser usados ​​em serviços da web.

Aman Goel
fonte
0

Pense neles como sinônimos, ambos têm um produtor que envia coisas para um consumidor ... No final, os campos das instâncias são gravados em um fluxo de bytes e a outra extremidade opõe-se ao contrário e segue as mesmas instâncias.

NB - O Java RMI também contém suporte para o transporte de classes ausentes do destinatário ...

mP.
fonte