Чим відрізняється серіалізація від маршалінгу?


521

Я знаю, що з точки зору декількох розподілених методик (наприклад, RPC) використовується термін "Маршалінг", але не розумію, чим він відрізняється від серіалізації. Чи не обидва вони перетворюють об'єкти в ряд біт?

Пов'язані:

Що таке серіалізація?

Що таке об'єктивний маршалінг?

Відповіді:


404

Маршалинга і сериализации є слабо синонімами в контексті віддаленого виклику процедур, але семантично різні як питання наміри.

Зокрема, маршалінг - це отримання параметрів звідти, а серіалізація - це копіювання структурованих даних у примітивну форму або з такої примітивної форми, як байт-потік. У цьому сенсі серіалізація - це один із засобів здійснення маршалінгу, як правило, реалізуючи семантику прохідних значень.

Також можливо об'єкт підлягати пошкодженню шляхом посилання, і в цьому випадку дані "на дроті" є просто інформацією про місце розташування для вихідного об'єкта. Однак такий об'єкт все ще може піддатися значенню серіалізації.

Як зазначає @Bill, можуть бути додаткові метадані, такі як розташування бази коду або навіть код реалізації об'єкта.


3
Чи є слово, яке означає серіалізацію та десеріалізацію одночасно? Потрібна назва інтерфейсу з цими методами.
raffian

1
@raffian, ти маєш на увазі інтерфейс, реалізований об'єктом, який піддається серіалізації та десеріалізації, або об'єктом, відповідальним за управління процесом? Ключові слова, які я б запропонував, - це "Serializable" та "Formatter" відповідно; прикрашати провідними I, змінами з великої літери тощо.
Джефрі Хантін

@JeffreyHantin Об'єктом, відповідальним за управління процесом, є те, що я мав на увазі; Зараз я використовую ISerializer, але це лише наполовину правильно :)
raffian

6
@raffian в телекомунікаціях, ми називаємо компонент, який серіалізує і десеріалізує "SerDes" або "serdes", як правило, вимовляється sir-dez або sir-deez, залежно від уподобань. Я припускаю, що він подібний до "модему" (тобто "Модулятора-демодулятора") за своєю конструкцією.
davidA

2
@naki - це всезагальна галузь - якщо ви подивитеся на високошвидкісні таблиці даних FPGA, вони згадають функціональність SERDES, хоча всі вони досить сучасні, починаючи з 1990-х. Google NGrams припускає, що він став більш популярним у 1980-х роках, хоча я знайшов примірник у таблиці даних IBM з 1970 року
davidA

207

Обоє роблять одне спільне - це серіалізація Об’єкта. Серіалізація використовується для передачі об'єктів або їх зберігання. Але:

  • Серіалізація: під час серіалізації об'єкта в потік байтів записуються лише дані учасників цього об'єкта; не код, який реально реалізує об'єкт.
  • Маршалінг: Термін Маршалінг використовується, коли ми говоримо про передачу Об'єкта віддаленим об'єктам (RMI) . У Маршаллінг Об'єкт серіалізується (дані членів серіалізуються) + Кодова база додається.

Тож серіалізація є частиною Маршалінгу.

CodeBase - це інформація, яка повідомляє одержувачу Object, де може бути знайдено реалізацію цього об'єкта. Будь-яка програма, яка думає, що коли-небудь може передати об’єкт іншій програмі, яка, можливо, не бачила його раніше, повинна встановити базу коду, щоб приймач міг знати, звідки завантажити код, якщо у нього немає локального коду. Після десеріалізації об'єкта одержувач отримає з нього базу коду і завантажить код з цього місця.


45
+1 для визначення того, що означає CodeBase у цьому контексті
Омар Салем

2
Маршалінг без серіалізації все ж відбувається. Див. Розділи Swing's invokeAndWaitта Forms Invoke, які маршалюють синхронний виклик до потоку інтерфейсу, не включаючи серіалізацію.
Джефрі Хантін

2
"не код, який реально реалізує об'єкт": Чи означає це методи класу? або що це означає Чи можете ви поясніть, будь ласка.
Вішал Ананд

2
Що ти маєш на увазі the implementation of this object? Чи можете ви навести конкретний приклад Serializationта Marshalling?
Сімін Джі

Маршалинг без серіалізації відбувається в деяких контекстах, наприклад, коли виклик функції передає потік керування між моделями різьблення (наприклад, між спільним пулом потоків і бібліотекою з одноконтактними потоками) в рамках одного процесу. Тому я кажу, що вони синонімічні в контексті RPC .
Джефрі Хантін

94

З статті Вікіпедії Marshalling (інформатика) :

Термін "маршал" вважається синонімом "серіалізувати" в стандартній бібліотеці Python 1 , але терміни не є синонімами в RFC 2713, пов'язаному з Java:

"Маршалити" об'єкт означає записувати його стан та бази коду таким чином, що коли об'єкт, який марширується, "не маршальований", отримує копію оригінального об'єкта, можливо, автоматично завантажуючи визначення класу об'єкта. Ви можете маршалити будь-який об'єкт, який можна піддавати серіалізації або віддалено. Маршаллінг - це як серіалізація, за винятком того, що маршалінг також записує кодові бази. Маршалінг відрізняється від серіалізації тим, що маршалінг спеціально обробляє віддалені об'єкти. (RFC 2713)

"Серіалізувати" об'єкт означає перетворити його стан у потік байтів таким чином, щоб байт-потік можна було перетворити назад у копію об'єкта.

Таким чином, маршал також зберігає кодову базу об'єкта в байтовому потоці на додаток до його стану.


1
Ви маєте на увазі Об'єкт, якщо несеріалізований, може просто мати стан, не буде жодної бази коду, тобто жодна його функція не може бути викликана, це лише структурований тип даних. І якщо один і той же об'єкт буде змінено, то він буде мати свою кодову базу разом зі структурою і колись може викликати його функції?
bjan

11
"Codebase" насправді не означає "Code". З розділу "Як працює Codebase" ( goo.gl/VOM2Ym ) Codebase - це просто те, як програми, що використовують семантику RMI-сеансу віддаленого завантаження класів, знаходять нові класи. Коли відправник об'єкта серіалізує цей об'єкт для передачі іншому JVM, він коментує серіалізований потік байтів з інформацією, що називається кодовою базою даних. Ця інформація повідомляє одержувачу, де можна знайти реалізацію цього об'єкта. Фактична інформація, що зберігається в анотації до кодової бази, - це список URL-адрес, з яких можна завантажити файл класу для потрібного об’єкта.
Джузеппе Бертоне

2
@Neurone Це визначення є специфічним для Джині та RMI. "Кодова база" - це загальний термін. en.wikipedia.org/wiki/Codebase
Білл Ящірка

2
@BilltheLizard Так, але оскільки ви говорите про маршалінг на Java, невірно говорити, що різниця між серіалізацією та маршалінгами полягає в тому, що "маршал зберігає код об'єкта на додаток до його стану", і це призводить до запитання bjan. Маршалінг зберігає "кодову базу" крім стану об'єкта.
Джузеппе Бертоне,

19

Я думаю, що головна відмінність полягає в тому, що Маршалінг нібито також включає кодову базу. Іншими словами, ви б не змогли маршалити та знеструмлювати об'єкт у еквівалентному державі екземпляру іншого класу. .

Серіалізація просто означає, що ви можете зберігати об'єкт і отримувати повторний стан, навіть якщо це екземпляр іншого класу.

За їх словами, вони зазвичай є синонімами.


2
Ви маєте на увазі, що об'єкт, якщо несеріалізований, може просто мати стан, не буде жодної бази коду, тобто жодна його функція не може бути викликана, це лише структурований тип даних. І якщо один і той же об'єкт буде змінено, то він буде мати свою кодову базу разом зі структурою, і ви можете викликати його функції?
bjan

18

Маршалінг відноситься до перетворення підпису та параметрів функції в єдиний байтовий масив. Спеціально для цілей RPC.

Частіше серіалізація стосується перетворення цілого дерева об'єктів / об'єктів у байтовий масив. Маршалінг буде серіалізувати параметри об'єкта з метою додавання їх до повідомлення та передачі по всій мережі. * Серіалізація може також використовуватися для зберігання на диску. *


11

Маршалінг - це правило розповісти компілятору, як дані будуть представлені в іншому середовищі / системі; Наприклад;

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

як ви бачите два різних значення рядка, представлені у вигляді різних типів значень.

Серіалізація конвертуватиме лише об'єктний вміст, а не представлення (залишиться незмінним) та підкорятиметься правилам серіалізації (що експортувати чи ні). Наприклад, приватні значення не будуть серіалізуватися, загальнодоступні значення так і структура об'єкта залишиться однаковою.


7

Ось більш конкретні приклади обох:

Приклад серіалізації:

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

При серіалізації дані вирівнюються таким чином, що вони можуть бути збережені та незапущені пізніше.

Демонстраційна демонстрація:

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

При маршалінгу дані не обов'язково повинні бути вирівняними, але їх потрібно перетворити на інше альтернативне подання. весь кастинг є маршируючим, але не всі марширування є кастинговими.

Маршалінг не вимагає участі динамічного розподілу, це може бути просто перетворення між структурами. Наприклад, у вас може бути пара, але функція очікує, що перший і другий елементи пари будуть інакше; ви кастинг / memcpy одну пару до іншої не виконаєте роботу, оскільки fst і snd будуть перевернуті.

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

Концепція маршалінгу стає особливо важливою, коли ви починаєте мати справу з позначеними об'єднаннями багатьох типів. Наприклад, вам може бути важко отримати механізм JavaScript, щоб надрукувати "c рядок" для вас, але ви можете попросити його надрукувати обернену рядок c для вас. Або якщо ви хочете надрукувати рядок із часу виконання JavaScript в Lua або Python. Всі вони є рядками, але часто не обійдуться без маршалінгу.

Нещодавно у мене було роздратування, що JScript масив маршала на C # як "__ComObject", і не має документально підтвердженого способу гри з цим об'єктом. Я можу знайти адресу, де він знаходиться, але я дійсно нічого іншого про це не знаю, тому єдиний спосіб дійсно зрозуміти це - будь-яким чином зазирнути в нього і, сподіваюся, знайти корисну інформацію про нього. Таким чином, стає легше створити новий об’єкт з дружнішим інтерфейсом, таким як Scripting.Dictionary, скопіювати в нього дані з об’єкта масиву JScript і передати цей об'єкт в C # замість масиву за замовчуванням JScript.

test.js:

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

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

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

вище надрукує "__ComObject", що є дещо чорною скринькою з точки зору C #.

Ще одна цікава концепція полягає в тому, що ви, можливо, маєте розуміння, як писати код, і комп'ютер, який знає, як виконувати вказівки, тому, як програміст, ви ефективно перебираєте концепцію того, що ви хочете, щоб комп'ютер робив від вашого мозку до програми зображення. Якби у нас було достатньо хороших маршалерів, ми могли б просто подумати, що ми хочемо зробити / змінити, і програма змінила б так, не набираючи клавіатури. Отже, якби у вас був спосіб зберігати всі фізичні зміни у вашому мозку протягом декількох секунд, де ви дійсно хочете написати крапку з комою, ви могли б перевести ці дані в сигнал для друку крапки з комою, але це крайність.


4

Маршалінг зазвичай знаходиться між відносно тісно пов'язаними процесами; серіалізація не обов'язково має таке очікування. Так, наприклад, при сумісному обміні даними між процесами, ви можете просто надіслати ПОСИЛАННЯ на потенційно дорогі дані для відновлення, тоді як при серіалізації ви б хотіли зберегти все, щоб належним чином відтворити об'єкти (об'єкти) при десеріалізації.


4

Моє розуміння маршового продажу відрізняється від інших відповідей.

Серіалізація:

Створення або повторне зволоження дротяної версії об'єктного графіка з використанням конвенції.

Маршируючий:

Створення або повторне зволоження дротяної версії об’єктного графіка за допомогою файлу відображення, щоб результати можна було налаштувати. Інструмент може починатись, дотримуючись конвенції, але важливою відмінністю є можливість налаштування результатів.

Перша контрактна розробка:

Маршаллінг важливий у контексті розробки першого контракту.

  • Можна внести зміни до внутрішнього графіка об'єкта, зберігаючи зовнішній інтерфейс стабільним у часі. Таким чином, всі абоненти послуг не повинні бути змінені для кожної дрібниці.
  • Можливо відображення результатів на різних мовах. Наприклад, від узгодження імені властивості однієї мови ('property_name') до іншої ('propertyName').

1
// Чи можу я дізнатися більше про те, що конкретно означає "регідрат" у цій відповіді тут, @JasperBlues? Я здогадуюсь, це не тільки для їжі космонавтів.
Натан Басанес

@NathanBasanese відповідно до цієї відповіді - stackoverflow.com/a/6991192/5101816 - визначення (повторного) зволоження містить такі слова: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

Основи Перші

Потік байтів - Потік - це послідовність даних. Вхідний потік - зчитує дані з джерела. Вихідний потік - записує дані в десинацію. Потоки байтів Java використовуються для виконання введення / виводу байтів за байтом (8 біт одночасно). Потік байтів підходить для обробки необроблених даних, таких як двійкові файли. Символьні потоки Java використовуються для виконання вводу / виводу 2 байти одночасно, оскільки символи зберігаються за допомогою конвенцій Unicode в Java з 2 байтами для кожного символу. Потік символів корисний, коли ми обробляємо (читаємо / записуємо) текстові файли.

RMI (Remote Method Invocation) - API, що забезпечує механізм створення розподіленого додатку в java. RMI дозволяє об’єкту викликати методи на об'єкт, що працює в іншому JVM.


І серіалізація, і маршаллінг вільно використовуються як синоніми. Ось кілька відмінностей.

Серіалізація - члени даних об'єкта записуються у двійкову форму або потік байтів (а потім можуть бути записані у файл / пам'ять / базу даних тощо). Інформація про типи даних не може зберігатися, коли члени об'єктних даних записуються у двійкову форму.

введіть тут опис зображення

Маршалинг - Об'єкт серіалізується (для байтового потоку у двійковому форматі) з типом даних + Кодова база, що додається, а потім передається Віддалений об'єкт (RMI) . Маршаллінг перетворить тип даних у заздалегідь визначений режим іменування, щоб його можна було реконструювати стосовно початкового типу даних. введіть тут опис зображення

Тож серіалізація є частиною Маршалінгу.

CodeBase - це інформація, яка повідомляє одержувачу Object, де може бути знайдено реалізацію цього об'єкта. Будь-яка програма, яка думає, що коли-небудь може передати об’єкт іншій програмі, яка, можливо, не бачила його раніше, повинна встановити базу коду, щоб приймач міг знати, звідки завантажити код, якщо у нього немає локального коду. Після десеріалізації об'єкта одержувач отримає з нього базу коду і завантажить код з цього місця. (Скопійовано з відповіді @Nasir)

Серіалізація майже нагадує дурне скидання пам'яті, яку використовують об'єкти (об'єкти), тоді як Marshalling зберігає інформацію про власні типи даних.

Певним чином, серіалізація виконує маршоутворення з реалізацією прохідного значення, оскільки не передається інформація типу даних, просто примітивна форма передається в байтовий потік.

Серіалізація може мати деякі проблеми, пов’язані з big-endian, small-endian, якщо потік переходить від однієї ОС до іншої, якщо різні ОС мають різні засоби представлення одних і тих же даних. З іншого боку, маршируючий процес цілком чудово мігрує між ОС, оскільки результат - представлення вищого рівня.


1

Маршалінг фактично використовує процес серіалізації, але основна відмінність полягає в тому, що в серіалізації лише члени даних і сам об'єкт отримують серіалізацію не підписи, а в кодовій базі коду Marshalling Object + (його реалізація) також трансформуються в байти.

Маршаллінг - це процес перетворення об’єкта java в об'єкти xml за допомогою JAXB, щоб він міг бути використаний у веб-службах.


0

Розгляньте їх як синоніми, обидва мають виробника, який надсилає речі споживачеві ... Зрештою, поля екземплярів записуються в байт-потік, а інший кінець вражає зворотний бік і з тими ж екземплярами.

NB - java RMI також містить підтримку транспортування класів, які відсутні у одержувача ...

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.