직렬화와 마샬링의 차이점은 무엇입니까?


답변:


404

마샬링 및 직렬화는 원격 프로 시저 호출의 맥락에서 느슨하게 동의하지만 의도적으로 의미 상 다릅니다.

특히, 마샬링은 여기에서 거기로 매개 변수를 가져 오는 것이지만 직렬화는 구조화 된 데이터를 바이트 스트림과 같은 기본 형식으로 복사하거나 복사하는 것에 관한 것입니다. 이러한 의미에서 직렬화는 마샬링을 수행하는 수단 중 하나이며 일반적으로 값별 의미를 구현합니다.

객체가 참조에 의해 마샬링 될 수도 있으며,이 경우 "와이어상의"데이터는 단순히 원래 객체에 대한 위치 정보이다. 그러나 이러한 개체는 여전히 직렬화를 중요하게 생각할 수 있습니다.

@Bill이 언급했듯이 코드 기반 위치 또는 객체 구현 코드와 같은 추가 메타 데이터가있을 수 있습니다.


3
직렬화와 직렬화 해제를 동시에 의미하는 단어가 있습니까? 해당 메소드와의 인터페이스 이름이 필요합니다.
raffian

1
@raffian, 직렬화 및 역 직렬화를 수행하는 객체 또는 프로세스 관리를 담당하는 객체에 의해 구현 된 인터페이스를 의미합니까? 내가 제안하는 핵심 단어는 각각 "Serializable"과 "Formatter"입니다. I필요에 따라 주요 , 대문자 변경 등으로 장식 하십시오.
Jeffrey Hantin

@JeffreyHantin 프로세스 관리를 담당하는 객체는 제가 의미 한 바입니다. 나는 지금 ISerializer를 사용하고 있지만, 반은 맞습니다 :)
raffian

6
통신에서 @raffian, 우리는 선호도에 따라 일반적으로 sir-dez 또는 sir-deez로 발음되는 "SerDes"또는 "serdes"를 직렬화하고 직렬화 해제하는 구성 요소를 호출합니다. 나는 그것이 구성에서 "모뎀"(즉, "모듈레이터-디모듈레이터")과 유사하다고 가정한다.
davidA

2
@naki 그것의 산업 전반 - 당신은 고속 FPGA의 데이터 시트를 보면 사람들은 1990 년대에 모두 매우 현대적인 가고 다시 있지만, 그들은, SERDES 기능을 언급 할 것이다. 구글 NGrams은 내가에서 IBM 데이터 시트에서 인스턴스를 발견했다하더라도 그것이 1980 년대에 더 인기가 제안 1970
davidA

207

둘 다 공통적으로 한 가지 일을합니다-그것은 객체를 직렬화 하는 것입니다. 직렬화는 객체를 전송하거나 저장하는 데 사용됩니다. 그러나:

  • 직렬화 : 개체를 직렬화하면 해당 개체 내의 멤버 데이터 만 바이트 스트림에 기록됩니다. 실제로 객체를 구현하는 코드가 아닙니다.
  • 마샬링 : 마샬링이라는 용어는 Object를 원격 객체 (RMI)전달하는 것에 대해 이야기 할 때 사용됩니다 . Marshalling Object에서 직렬화 됨 (멤버 데이터가 직렬화 됨) + 코드베이스가 첨부됩니다.

직렬화는 마샬링의 일부입니다.

CodeBase 는이 객체의 구현을 찾을 수있는 곳의 Object 수신자에게 알려주는 정보입니다. 이전에 보지 못한 다른 프로그램으로 객체를 전달할 수 있다고 생각하는 프로그램은 코드베이스를 설정해야 코드를 로컬에서 사용할 수없는 경우 수신자가 코드를 다운로드 할 위치를 알 수 있습니다. 수신자는 객체를 직렬화 해제 할 때 객체에서 코드베이스를 가져와 해당 위치에서 코드를로드합니다.


45
이 맥락에서 CodeBase의 의미 를 정의한 +1
Omar Salem

2
직렬화가없는 마샬링이 발생합니다. 직렬화없이 UI 스레드에 대한 동기 호출을 마샬링하는 Swing invokeAndWait및 Forms를 참조하십시오 Invoke.
Jeffrey Hantin

2
"실제로 개체를 구현하는 코드가 아닙니다": 클래스 메서드를 의미합니까? 또는 이것이 무엇을 의미합니까? 설명해 주시겠습니까?
Vishal Anand

2
무슨 소리 야 the implementation of this object? 당신은 특정의 예를 줄 수 SerializationMarshalling?
Simin Jie

함수 호출이 단일 프로세스 내에서 스레딩 모델 간 (예 : 공유 스레드 풀과 단일 고정 스레드 라이브러리 간) 제어 흐름을 전송하는 경우와 같이 일부 컨텍스트에서는 직렬화없는 마샬링 발생합니다. 그렇기 때문에 RPC 맥락에서 느슨하게 동의어라고 말합니다 .
Jeffrey Hantin

94

로부터 마샬링 (컴퓨터 과학) Wikipedia 기사 :

"marshal"이라는 용어는 Python 표준 라이브러리에서 "serialize"와 동의어로 간주됩니다 1 되지만 Java 관련 RFC 2713에서는 동의어가 아닙니다.

객체를 "마샬링"한다는 것은 마샬링 된 객체가 "비 마샬링"될 때 객체의 클래스 정의를 자동으로로드하여 원래 객체의 사본을 얻는 방식으로 상태 및 코드베이스를 기록하는 것을 의미합니다. 직렬화 가능하거나 원격 인 모든 오브젝트를 마샬링 할 수 있습니다. 마샬링은 코드베이스를 기록한다는 점을 제외하면 직렬화와 비슷합니다. 마샬링은 마샬링이 원격 객체를 특별히 처리한다는 점에서 직렬화와 다릅니다. (RFC 2713)

객체를 "직렬화"한다는 것은 바이트 스트림이 객체의 복사본으로 다시 변환 될 수있는 방식으로 상태를 바이트 스트림으로 변환하는 것을 의미합니다.

따라서 마샬링 은 객체 의 코드베이스 를 상태 외에도 바이트 스트림에 저장합니다 .


1
직렬화되지 않은 Object는 상태를 가질 수 있으며 코드베이스가 없으므로 함수를 호출 할 수 없으며 구조화 된 데이터 유형 일뿐입니다. 그리고 동일한 객체가 마샬링되면 구조와 함께 코드베이스가 있고 함수를 호출 할 수 있습니까?
bjan

11
"코드베이스"는 실제로 "코드"를 의미하지 않습니다. "Codebase의 작동 방식"( goo.gl/VOM2Ym )에서 Codebase는 RMI의 원격 클래스 로딩 시맨틱을 사용하는 프로그램이 새로운 클래스를 찾는 방법입니다. 객체의 발신자가 다른 JVM으로 전송하기 위해 해당 객체를 직렬화하면 직렬화 된 바이트 스트림에 코드베이스라고하는 정보가 표시됩니다. 이 정보는 수신자에게이 오브젝트의 구현을 찾을 수있는 위치를 알려줍니다. 코드베이스 주석에 저장된 실제 정보는 필요한 객체의 클래스 파일을 다운로드 할 수있는 URL 목록입니다.
Giuseppe Bertone

2
@Neurone이 정의는 Jini 및 RMI에만 해당됩니다. "코드베이스"는 일반적인 용어입니다. en.wikipedia.org/wiki/Codebase
Bill the Lizard

2
@BilltheLizard 그래,하지만 Java에서 마샬링에 대해 이야기하고 있기 때문에 직렬화와 마샬링의 차이점은 "마샬링은 객체 코드를 상태와 함께 저장합니다"라는 말은 잘못이며 bjan의 질문으로 이어집니다. 마샬링은 객체 상태 외에도 "코드베이스"를 저장합니다.
Giuseppe Bertone

19

주요 차이점은 Marshalling이 코드베이스와 관련이 있다고 생각합니다. 즉, 객체를 다른 클래스의 상태와 동등한 인스턴스로 마샬링 및 마샬링 해제 할 수 없습니다. .

직렬화는 객체가 다른 클래스의 인스턴스 인 경우에도 객체를 저장하고 동등한 상태를 다시 얻을 수 있음을 의미합니다.

즉, 일반적으로 동의어입니다.


2
직렬화되지 않은 Object는 상태를 가질 수 있으며 코드베이스가 없으며 즉 함수를 호출 할 수 없으며 구조적 데이터 유형 일뿐입니다. 그리고 동일한 객체가 마샬링되면 구조와 함께 코드베이스가 있고 함수를 호출 할 수 있습니까?
bjan

18

마샬링은 함수의 서명과 매개 변수를 단일 바이트 배열로 변환하는 것을 말합니다. 특히 RPC를 목적으로합니다.

직렬화는 종종 전체 객체 / 객체 트리를 바이트 배열로 변환하는 것을 말합니다. Marshaling은 객체 매개 변수를 직렬화하여 메시지에 추가하고 네트워크를 통해 전달합니다. * 직렬화는 디스크에 저장하기 위해 사용할 수있다. *


11

마샬링 은 다른 환경 / 시스템에서 데이터가 표현되는 방식을 컴파일러에 알리는 규칙입니다. 예를 들어;

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

두 개의 다른 문자열 값이 다른 값 유형으로 표시되는 것을 볼 수 있습니다.

직렬화 는 표현이 아닌 객체 내용 만 변환하고 (동일하게 유지됨) 직렬화 규칙을 준수합니다 (내보낼 항목 또는없는 항목). 예를 들어 개인 값은 직렬화되지 않으며 공개 값은 yes이며 개체 구조는 동일하게 유지됩니다.


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

마샬링에서 데이터를 반드시 평면화 할 필요는 없지만 다른 대체 표현으로 변환해야합니다. 모든 캐스팅이 마샬링되지만 모든 마샬링이 캐스팅은 아닙니다.

마샬링에는 동적 할당이 필요하지 않으며 구조체 간의 변환 일 수도 있습니다. 예를 들어, 페어가있을 수 있지만이 함수는 페어의 첫 번째 요소와 두 번째 요소가 다른 방식 일 것으로 예상합니다. fst와 snd가 뒤집어지기 때문에 한 쌍을 다른 쌍으로 캐스팅 / memcpy하면 작업을 수행하지 않습니다.

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

마샬링의 개념은 여러 유형의 태그가 지정된 조합을 처리 할 때 특히 중요합니다. 예를 들어, "c 문자열"을 인쇄하기 위해 JavaScript 엔진을 얻는 것이 어려울 수 있지만 랩핑 된 c 문자열을 인쇄하도록 요청할 수 있습니다. 또는 Lua 또는 Python 런타임의 JavaScript 런타임에서 문자열을 인쇄하려는 경우. 그것들은 모두 문자열이지만 종종 마샬링하지 않고는 어울리지 않습니다.

최근에 JScript 배열이 C #에 "__ComObject"로 마샬링되어이 개체를 재생할 수있는 문서화 된 방법이 없었습니다. 나는 그것이 어디에 있는지에 대한 주소를 찾을 수 있지만, 나는 그것에 대해 다른 것을 전혀 모른다. 그래서 실제로 그것을 알아낼 수있는 유일한 방법은 가능한 어떤 방식 으로든 그것을 찌르고 그것에 대해 유용한 정보를 찾는 것입니다. 따라서 Scripting.Dictionary와 같은보다 친숙한 인터페이스를 사용하여 새 객체를 만드는 것이 더 쉬워지고 JScript 배열 객체의 데이터를 복사하여 JScript의 기본 배열 대신 C #에 전달합니다.

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

위의 "__ComObject"는 C #의 관점에서 볼 때 다소 블랙 박스입니다.

또 다른 흥미로운 개념은 코드 작성 방법과 명령 실행 방법을 알고있는 컴퓨터에 대한 이해가있을 수 있으므로 프로그래머는 컴퓨터가 두뇌에서 프로그램으로 수행하려는 작업의 개념을 효과적으로 마샬링하는 것입니다 영상. 마샬 러가 충분하다면, 우리가하고 싶은 일 / 변경을 생각할 수있을뿐 아니라 키보드를 입력하지 않아도 프로그램이 변경 될 것입니다. 따라서 실제로 세미콜론을 작성하려는 몇 초 동안 뇌의 모든 신체적 변화를 저장할 수있는 방법이 있다면 해당 데이터를 신호에 마샬링하여 세미콜론을 인쇄 할 수는 있지만 극단적입니다.


4

마샬링은 일반적으로 비교적 밀접한 관련 프로세스 사이에 있습니다. 직렬화에 반드시 그런 기대가있는 것은 아닙니다. 예를 들어 프로세스간에 데이터를 마샬링하는 경우 복구하기 위해 잠재적으로 고가의 데이터에 대한 참조를 보내려고하지만 직렬화를 사용하면 역 직렬화 할 때 오브젝트를 올바르게 다시 작성하기 위해 모두 저장하는 것이 좋습니다.


4

마샬링에 대한 나의 이해는 다른 답변과 다릅니다.

직렬화 :

규칙을 사용하여 와이어 형식 버전의 객체 그래프를 생성하거나 재수 화합니다.

마샬링 :

매핑 파일을 사용하여 와이어 형식 버전의 객체 그래프를 생성하거나 재수 화하여 결과를 사용자 지정할 수 있습니다. 도구는 규칙을 준수하여 시작할 수 있지만 중요한 차이점은 결과를 사용자 정의하는 기능입니다.

최초 계약 개발 :

마샬링은 계약 첫 개발의 맥락에서 중요합니다.

  • 시간이 지남에 따라 외부 인터페이스를 안정적으로 유지하면서 내부 객체 그래프를 변경할 수 있습니다. 이렇게하면 모든 사소한 변경에 대해 모든 서비스 가입자를 수정할 필요가 없습니다.
  • 다른 언어로 결과를 매핑 할 수 있습니다. 예를 들어 한 언어 ( 'property_name')의 속성 이름 규칙에서 다른 언어 ( 'propertyName')까지입니다.

1
//, 특히 "재수 화"가 무엇을 의미하는지 더 알고 싶습니다. 나는 그것이 우주 비행사 음식만을위한 것이 아니라고 추측합니다.
Nathan Basanese

-이 응답에 따른 @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

기본 사항

바이트 스트림 -스트림은 데이터 시퀀스입니다. 입력 스트림-소스에서 데이터를 읽습니다. 출력 스트림-데이터를 desitnation에 기록합니다. Java 바이트 스트림은 바이트 단위로 입출력을 수행하는 데 사용됩니다 (한 번에 8 비트). 바이트 스트림은 이진 파일과 같은 원시 데이터를 처리하는 데 적합합니다. Java 문자 스트림은 한 번에 2 바이트 씩 입력 / 출력을 수행하는 데 사용됩니다. 문자는 각 문자마다 2 바이트로 Java에서 유니 코드 규칙을 사용하여 저장되기 때문입니다. 문자 스트림은 텍스트 파일을 처리 (읽기 / 쓰기) 할 때 유용합니다.

RMI (Remote Method Invocation)-Java로 분산 애플리케이션을 작성하는 메커니즘을 제공하는 API입니다. RMI는 객체가 다른 JVM에서 실행되는 객체에서 메소드를 호출 할 수 있도록합니다.


직렬화마샬링 은 모두 동의어로 느슨하게 사용됩니다. 몇 가지 차이점이 있습니다.

직렬화 -객체의 데이터 멤버는 이진 형식 또는 바이트 스트림으로 작성된 다음 파일 / 메모리 / 데이터베이스 등으로 쓸 수 있습니다. 오브젝트 데이터 멤버가 2 진 형식으로 작성된 후에는 데이터 유형에 대한 정보를 보유 할 수 없습니다.

여기에 이미지 설명을 입력하십시오

Marshalling -Object는 data-type + Codebase가 연결된 상태에서 직렬화 (2 진 형식의 바이트 스트림으로) 된 다음 Remote Object (RMI) 전달 됩니다. 마샬링은 데이터 유형을 사전 결정된 명명 규칙으로 변환하여 초기 데이터 유형과 관련하여 재구성 할 수 있습니다. 여기에 이미지 설명을 입력하십시오

직렬화는 마샬링의 일부입니다.

CodeBase 는이 객체의 구현을 찾을 수있는 곳의 Object 수신자에게 알려주는 정보입니다. 이전에 보지 못한 다른 프로그램으로 객체를 전달할 수 있다고 생각하는 프로그램은 코드베이스를 설정해야 코드를 로컬에서 사용할 수없는 경우 수신자가 코드를 다운로드 할 위치를 알 수 있습니다. 수신자는 객체를 직렬화 해제 할 때 객체에서 코드베이스를 가져와 해당 위치에서 코드를로드합니다. (@Nasir 답변에서 복사)

직렬화 는 객체가 사용하는 메모리의 바보 같은 메모리 덤프와 거의 비슷하지만 Marshalling 은 사용자 정의 데이터 유형에 대한 정보를 저장합니다.

어떤 방식으로, 직렬화는 데이터 유형의 정보가 전달되지 않고 기본 형식 만 바이트 스트림으로 전달되므로 값별 전달을 구현하여 마샬링을 수행합니다.

다른 OS에 동일한 데이터를 나타내는 다른 수단이있는 경우 스트림이 한 OS에서 다른 OS로 이동하는 경우 직렬화에는 빅 엔디안, 소규모 엔디안과 관련된 일부 문제가있을 수 있습니다. 반면 마샬링은 결과가 상위 ​​수준이기 때문에 OS간에 마이그레이션하는 것이 좋습니다.


1

마샬링은 실제로 직렬화 프로세스를 사용하지만 가장 큰 차이점은 직렬화에서는 데이터 멤버 및 객체 자체 만 서명이 아닌 직렬화되지만 Marshalling Object + 코드베이스 (구현)에서도 바이트로 변환된다는 것입니다.

Marshalling은 JAXB를 사용하여 Java 객체를 xml 객체로 변환하여 웹 서비스에서 사용할 수 있도록하는 프로세스입니다.


0

그것들을 동의어로 생각하면, 둘 다 소비자에게 물건을 보내는 생산자를 가지고 있습니다.

NB-java RMI에는 수신자로부터 누락 된 클래스를 전송하는 기능도 포함되어 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.