Serileştirme ve Marshaling arasındaki fark nedir?


Yanıtlar:


404

Sıradanlaştırma ve serileştirme, uzak yordam çağrısı bağlamında gevşekçe eş anlamlıdır, ancak niyet meselesi olarak anlamsal olarak farklıdır.

Özellikle marşlama, buradan oraya parametreler almakla ilgilidir, serileştirme ise yapılandırılmış verileri bir bayt akışı gibi ilkel bir forma veya ondan bir formdan kopyalamakla ilgilidir. Bu anlamda, serileştirme, genellikle by-pass semantik uygulayan, marşaling yapmak için bir araçtır.

Bir nesnenin referans olarak sıralanması da mümkündür, bu durumda "tel üzerindeki" veriler sadece orijinal nesnenin konum bilgisi olur. Bununla birlikte, böyle bir nesne değer serileştirmesine hala uygun olabilir.

@Bill'den bahsedildiği gibi, kod tabanı konumu ve hatta nesne uygulama kodu gibi ek meta veriler olabilir.


3
Aynı anda serileştirmek ve serileştirmek anlamına gelen bir kelime var mı? Bu yöntemlere sahip bir arayüz için bir ad gerekiyor.
raffian

1
@raffian, serileştirme ve serileştirme uygulanan nesne veya süreci yönetmekten sorumlu nesne tarafından uygulanan bir arabirim anlamına mı geliyor? Önereceğim anahtar kelimeler sırasıyla "Serializable" ve "Formatter"; liderlik I, büyük harf değişiklikleri ve benzerleri ile süsleyin .
Jeffrey Hantin

@JeffreyHantin Süreci yönetmekten sorumlu bir nesne, kastettiğim şeydi; Şimdi ISerializer kullanıyorum, ama bu sadece yarısı doğru :)
raffian

6
Telekomünikasyonda @raffian, tercihe bağlı olarak genellikle sir-dez veya sir-deez olarak telaffuz edilen bir "SerDes" veya "serdes" serileştiren ve serileştiren bir bileşen olarak adlandırıyoruz. Sanırım yapısında "modeme" (yani "Modülatör-Demodülatör") benziyor.
davidA

2
@naki endüstri çapında - yüksek hızlı FPGA veri sayfalarına bakarsanız, SERDES işlevselliğinden bahsedecekler, ancak bunların hepsi oldukça modern olmasına rağmen, 1990'lara geri dönüyor. Google NGrams , 1970'lerde
davidA

207

Her ikisi de ortak bir şey yapar - bu bir Nesneyi serileştirir . Serileştirme, nesneleri aktarmak veya saklamak için kullanılır. Fakat:

  • Serileştirme: Bir nesneyi serileştirdiğinizde, bayt akışına yalnızca o nesne içindeki üye verileri yazılır; aslında nesneyi uygulayan kod değil.
  • Marshalling: Marshalling terimi, Object'i uzaktaki nesnelere (RMI) geçirmekten söz ettiğimizde kullanılır . Marshalling'de Nesne serileştirilir (üye verileri serileştirilir) + Kod tabanı eklenir.

Yani Serilaşma Marshalling'in bir parçasıdır.

CodeBase , Object alıcısına bu nesnenin uygulanmasının nerede bulunabileceğini bildiren bilgidir. Bir nesneyi daha önce görmemiş olabilecek başka bir programa geçirebileceğini düşünen herhangi bir programın kod tabanını ayarlaması gerekir, böylece alıcının kodu yerel olarak mevcut değilse nereden indireceğini bilmesi gerekir. Alıcı, nesnenin serisini kaldırdıktan sonra, kod tabanını ondan alır ve kodu bu konumdan yükler.


45
CodeBase'in bu bağlamda ne anlama geldiğini tanımlamak için +1
Omar Salem

2
Serileştirme olmadan ağlama gerçekleşir. Bkz . Serileştirme olmadan UI iş parçacığına eşzamanlı çağrı yapan Swing invokeAndWaitve Forms's Invoke.
Jeffrey Hantin

2
"nesneyi uygulayan kod değil": Bu sınıf yöntemleri anlamına mı geliyor? ya da bu ne anlama geliyor. Açıklayabilir misin.
Vishal Anand

2
Ne demek istiyorsun the implementation of this object? Eğer belirli bir örnek verebilir Serializationve Marshalling?
Simin Jie

Marshalling serileştirme olmadan böyle bir işlev çağrısı transferleri tek bir süreç içinde (ortak iş parçacığı havuzu ve tek sabitlenmiş iplik kütüphanesi arasında, örneğin) diş modelleri arasında akış kontrolü gibi bazı bağlamlarda olur. Bu yüzden RPC bağlamında gevşek olduklarını söylüyorum .
Jeffrey Hantin

94

Gönderen sıralanırken (bilgisayar bilimi) Vikipedi makalesinde:

"Mareşal" terimi, Python standart kitaplığı 1'deki "serileştirme" ile eşanlamlı olarak kabul edilir , ancak terimler Java ile ilgili RFC 2713'te eşanlamlı değildir:

Bir nesneyi "mareşal" etmek, durumunu ve kod tabanlarını, sıralı nesne "sıralanmamış" olduğunda, muhtemelen nesnenin sınıf tanımlarını otomatik olarak yükleyerek orijinal nesnenin bir kopyasını elde edilecek şekilde kaydetmek anlamına gelir. Serileştirilebilir veya uzak herhangi bir nesneyi marshal yapabilirsiniz. Marshalling serileştirme gibidir, ancak marshalling kod tabanlarını da kaydeder. Marshalling, serileştirmenin uzaktaki nesnelere özel davranması nedeniyle serileştirmeden farklıdır. (RFC 2713)

Bir nesneyi "serileştirmek", bayt akışının nesnenin bir kopyasına dönüştürülebileceği şekilde durumunu bir bayt akışına dönüştürmek anlamına gelir.

Böylece marshalling , bir nesnenin kod tabanını , durumuna ek olarak bayt akışına da kaydeder .


1
Eğer bir nesne, dizileştirilmemişse, sadece bir duruma sahip olabilir, herhangi bir kod tabanı olmayacaktır, yani işlevinin hiçbiri çağrılamaz, sadece yapılandırılmış bir veri türüdür. Ve eğer aynı nesne sıralanırsa, o zaman kod yapısı ile birlikte tabanına sahip olacak ve bir kez fonksiyonlarını çağırabilir mi?
bjan

11
"Kod tabanı" gerçekten "Kod" anlamına gelmez. " Codebase Nasıl Çalışır" ( goo.gl/VOM2Ym ) Codebase , oldukça basit bir şekilde, RMI'nin uzaktan sınıf yüklemesi semantiğini kullanan programların nasıl yeni sınıflar bulduğunu gösterir. Bir nesnenin göndericisi, başka bir JVM'ye iletilmek üzere o nesneyi serileştirdiğinde, kod tabanı adı verilen bilgilerle serileştirilmiş bayt akışına açıklama ekler. Bu bilgi, alıcıya bu nesnenin uygulanmasının nerede bulunabileceğini bildirir. Kod tabanı ek açıklamasında saklanan gerçek bilgiler, gerekli nesne için sınıf dosyasının indirilebileceği URL'lerin listesidir.
Giuseppe Bertone

2
@Neurone Bu tanım Jini ve RMI için geçerlidir. "Kod tabanı" genel bir terimdir. tr.wikipedia.org/wiki/Codebase
Bill the Lizard

2
@BilltheLizard Evet, ancak Java'da marshalling'den bahsettiğiniz için, serileştirme ve marshalling arasındaki farkın "marshalling, nesnenin kodunu durumuna ek olarak kaydettiğini" söylemek yanlış olur ve bjan'ın sorusuna yol açar. Marshalling, nesne durumuna ek olarak "kod tabanını" kaydeder.
Giuseppe Bertone

19

Bence en büyük fark Marshalling'in kod tabanını da içermesi. Başka bir deyişle, bir nesneyi farklı bir sınıfın durum eşdeğeri örneğinde mareşal ve mareşalsiz yapamazsınız. .

Serileştirme, nesneyi depolayabileceğiniz ve başka bir sınıf örneği olsa bile eşdeğer bir durumu yeniden elde edebileceğiniz anlamına gelir.

Bununla birlikte, bunlar genellikle eşanlamlıdır.


2
Eğer bir nesne, dizileştirilmemişse, sadece bir duruma sahip olabilir, herhangi bir kod tabanı olmayacaktır, yani işlevlerinden hiçbiri çağrılamaz, sadece yapılandırılmış bir veri türüdür. Ve eğer aynı nesne sıraya konursa, o zaman kod yapısı ile birlikte temelini alacaktır ve işlevlerini çağırabilir mi?
bjan

18

Marshaling, bir işlevin imzasını ve parametrelerini tek bir bayt dizisine dönüştürmeyi ifade eder. Özellikle RPC için.

Serileştirme daha çok tüm nesne / nesne ağacının bir bayt dizisine dönüştürülmesini ifade eder. Marshaling, nesne parametrelerini mesaja eklemek ve ağ üzerinden geçirmek için serileştirir. * Serileştirme ayrıca diske depolamak için de kullanılabilir.


11

Marshalling , derleyiciye verilerin başka bir ortamda / sistemde nasıl temsil edileceğini söyleme kuralıdır; Örneğin;

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

farklı değer türleri olarak gösterilen iki farklı dize değeri görebilirsiniz.

Serileştirme , yalnızca nesne içeriğini dönüştürür, temsili değil (aynı kalacaktır) ve serileştirme kurallarına (ne dışa aktarılacağı ya da hayır verilemez) uyar. Örneğin, özel değerler serileştirilmez, genel değerler evet ve nesne yapısı aynı kalır.


7

İşte her ikisinin daha spesifik örnekleri:

Serileştirme Örneği:

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

Serileştirmede, veriler daha sonra saklanabilecek ve düzleştirilemeyecek şekilde düzleştirilir.

Marshalling Demosu:

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

Birleştirmede, verilerin düzleştirilmesi gerekmez, ancak başka bir alternatif temsile dönüştürülmesi gerekir. tüm dökümler marşalıyor, ama tüm marşalingler döküm değil.

Marshaling, dinamik ayırmanın dahil edilmesini gerektirmez, aynı zamanda yapılar arasında dönüşüm de olabilir. Örneğin, bir çiftiniz olabilir, ancak işlev, çiftin birinci ve ikinci öğelerinin başka bir şekilde olmasını bekler; Eğer bir çifti diğerine döküm / memcpy iş yapmaz çünkü fst ve snd çevrilir.

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

Birçok türdeki etiketli sendikalarla uğraşmaya başladığınızda, marshaling kavramı özellikle önem kazanıyor. Örneğin, sizin için bir "c dizesi" yazdırmak için bir JavaScript motoru edinmek zor olabilir, ancak sizin için bir sarılmış c dizesi yazdırmasını isteyebilirsiniz. Veya bir Lua veya Python çalışma zamanında JavaScript çalışma zamanından bir dize yazdırmak istiyorsanız. Hepsi ipler, ama çoğu zaman marş etmeden geçinemezler.

Son zamanlarda yaşadığım bir sıkıntı, JScript'in mareşali C # 'a "__ComObject" olarak dizmesi ve bu nesneyle oynamak için belgelenmiş bir yolu olmamasıydı. Nerede olduğunun adresini bulabilirim, ama gerçekten onun hakkında başka bir şey bilmiyorum, bu yüzden gerçekten anlamanın tek yolu ona mümkün olan her şekilde sokmak ve umarım bu konuda yararlı bilgiler bulmaktır. Böylece Scripting.Dictionary gibi daha dostça bir arayüzle yeni bir nesne oluşturmak, JScript dizi nesnesinden verileri kopyalamak ve bu nesneyi JScript'in varsayılan dizisi yerine C # 'a aktarmak daha kolay hale gelir.

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

yukarıdaki "__ComObject", C # açısından bir kara kutu biraz yazdırır.

Bir başka ilginç kavram, kodun nasıl yazılacağını anlamanız ve talimatların nasıl yürütüleceğini bilen bir bilgisayara sahip olmanızdır, bu nedenle bir programcı olarak, bilgisayarın beyninizden programa ne yapmasını istediğinizi kavramını etkili bir şekilde paylaşıyorsunuz. görüntüsü. Yeterince iyi marshaller'larımız olsaydı, sadece ne yapmak / değiştirmek istediğimizi düşünebilirdik ve program klavyeye yazmadan bu şekilde değişecekti. Yani, gerçekten bir noktalı virgül yazmak istediğiniz birkaç saniye boyunca beyninizdeki tüm fiziksel değişiklikleri saklamanın bir yoluna sahip olabilirseniz, bu verileri noktalı virgül yazdırmak için bir sinyale dönüştürebilirsiniz, ancak bu aşırıdır.


4

Marshalling genellikle nispeten yakından ilişkili süreçler arasındadır; Serileştirmenin mutlaka bu beklentisi yoktur. Bu nedenle, örneğin işlemler arasında veri paylaşırken, kurtarmak için potansiyel olarak pahalı verilere yalnızca bir REFERENCE göndermek istersiniz, oysa serileştirme ile, serileştirildiğinde nesneleri düzgün bir şekilde yeniden oluşturmak için hepsini kaydetmek istersiniz.


4

Benim marshalling anlayışım diğer cevaplardan farklı.

Serile:

Bir kural kullanarak bir nesne grafiğinin tel formatlı bir versiyonunu üretmek veya rehidrate etmek.

Marshalling:

Bir eşleme dosyası kullanarak bir nesne grafiğinin tel biçimindeki bir sürümünü üretmek veya rehidrate etmek, böylece sonuçlar özelleştirilebilir. Araç, bir kurala bağlı kalarak başlayabilir, ancak önemli fark sonuçları özelleştirme yeteneğidir.

Sözleşme İlk Geliştirme:

Marshalling, sözleşmenin ilk gelişimi bağlamında önemlidir.

  • Harici arayüzü zaman içinde sabit tutarken, dahili bir nesne grafiğinde değişiklik yapmak mümkündür. Bu şekilde, tüm hizmet abonelerinin her önemli değişiklik için değiştirilmesi gerekmez.
  • Sonuçları farklı dillerde eşlemek mümkündür. Örneğin, bir dilin ('özellik_adı') özellik adı kuralından diğerine ('özellikAdı').

1
//, Buradaki cevapta, @JasperBlues, özellikle, "rehidrat" ne anlama geldiği hakkında daha fazla bilgi alabilir miyim? Sanırım sadece Astronot yemekleri için değil.
Nathan Basanese

@NathanBasanese bu yanıta göre - stackoverflow.com/a/6991192/5101816 - (yeniden) nemlendirmenin tanımı aşağıdaki kelimeleri içerir: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

Önce Temel Bilgiler

Bayt Akışı - Akış, veri dizisidir. Giriş akışı - verileri kaynaktan okur. Çıktı akışı - verileri desitnasyona yazar. Java Bayt Akımları, girdi / çıktı bayt baytını (bir seferde 8 bit) gerçekleştirmek için kullanılır. Bayt akışı, ikili dosyalar gibi ham verileri işlemek için uygundur. Java Karakter Akışları bir kerede giriş / çıkış 2 bayt gerçekleştirmek için kullanılır, çünkü Karakterler her karakter için 2 baytlık Java'da Unicode kuralları kullanılarak saklanır. Metin akışı işlendiğinde (okurken / yazılırken) karakter akışı yararlıdır.

RMI (Uzaktan Yöntem Çağırma) - Java'da dağıtılmış uygulama oluşturmak için bir mekanizma sağlayan bir API. RMI, bir nesnenin başka bir JVM'de çalışan bir nesne üzerindeki yöntemleri çağırmasına izin verir.


Hem Serileştirme hem de Marshalling , eşanlamlı olarak gevşek bir şekilde kullanılır. İşte birkaç fark.

Serileştirme - Bir nesnenin veri üyeleri ikili forma veya Byte Stream'e yazılır (ve daha sonra dosya / bellek / veritabanı vb. Şeklinde yazılabilir). Nesne veri üyeleri ikili forma yazıldıktan sonra veri türleri hakkında hiçbir bilgi saklanamaz.

resim açıklamasını buraya girin

Marshalling - Nesne, veri türü + Codebase eklenmiş ve daha sonra Uzak Nesne (RMI) geçirilerek serileştirilmiştir (ikili biçimde bayt akışına ) . Marshalling, veri türünü, önceden belirlenmiş bir adlandırma kuralına dönüştürür, böylece ilk veri türüne göre yeniden yapılandırılabilir. resim açıklamasını buraya girin

Yani Serilaşma Marshalling'in bir parçasıdır.

CodeBase , Object alıcısına bu nesnenin uygulanmasının nerede bulunabileceğini bildiren bilgidir. Bir nesneyi daha önce görmemiş olabilecek başka bir programa geçirebileceğini düşünen herhangi bir programın kod tabanını ayarlaması gerekir, böylece alıcının kodu yerel olarak mevcut değilse nereden indireceğini bilmesi gerekir. Alıcı, nesnenin serisini kaldırdıktan sonra, kod tabanını ondan alır ve kodu bu konumdan yükler. (@Nasir yanıtından kopyalandı)

Serileştirme neredeyse nesneler tarafından kullanılan belleğin aptal bir bellek dökümü gibidir, Marshalling özel veri türleri hakkında bilgi depolar.

Bir şekilde, Serileştirme, veri değeri bilgisi geçirilmediğinden, sadece ilkel form bayt akışına iletildiğinden, by-pass değerinin uygulanmasıyla sıralama yapar.

Farklı işletim sisteminin aynı verileri temsil etmenin farklı araçları varsa, akış bir işletim sisteminden diğerine gidiyorsa, seri hale getirmenin big-endian, small-endian ile ilgili bazı sorunları olabilir. Öte yandan, marshalling, işletim sistemi arasında geçiş yapmak için mükemmel derecede iyidir, çünkü sonuç daha üst düzey bir sunumdur.


1

Marshaling aslında Serileştirme sürecini kullanır, ancak en büyük fark, Serileştirmedeki sadece veri üyelerinin ve nesnenin kendisinin imza değil serileştirilmiş olması, ancak Marshalling Object + kod tabanında (uygulaması) da baytlara dönüştürülmesidir.

Marshalling, web hizmetlerinde kullanılabilmesi için java nesnesini JAXB kullanarak xml nesnelerine dönüştürme işlemidir.


0

Bunları eşanlamlılar olarak düşünün, her ikisinin de bir tüketiciye bir şeyler gönderen bir üreticisi var ... Örneklerin son alanlarında bir bayt akışına yazılır ve diğer uç da tersi ve aynı örneklerle yukarı bakar.

NB - Java RMI, alıcıdan eksik olan sınıfların taşınması için destek de içerir ...

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.