Sự khác biệt giữa serialization và Marshaling là gì?


Câu trả lời:


405

Marsh Marsh và serialization là đồng nghĩa lỏng lẻo trong bối cảnh của cuộc gọi thủ tục từ xa, nhưng khác nhau về mặt ngữ nghĩa là một vấn đề của ý định.

Cụ thể, sắp xếp theo thứ tự là về việc lấy các tham số từ đây đến đó, trong khi tuần tự hóa là về việc sao chép dữ liệu có cấu trúc sang hoặc từ một dạng nguyên thủy như luồng byte. Theo nghĩa này, tuần tự hóa là một phương tiện để thực hiện việc sắp xếp theo thứ tự, thường là thực hiện ngữ nghĩa truyền qua giá trị.

Cũng có thể một đối tượng được sắp xếp theo tham chiếu, trong trường hợp đó, dữ liệu "trên dây" chỉ đơn giản là thông tin vị trí cho đối tượng ban đầu. Tuy nhiên, một đối tượng như vậy vẫn có thể tuân theo giá trị tuần tự hóa.

Như @Bill đề cập, có thể có siêu dữ liệu bổ sung như vị trí cơ sở mã hoặc thậm chí mã triển khai đối tượng.


3
Có một từ có nghĩa là tuần tự hóa và giải tuần tự hóa cùng một lúc? Cần một tên cho một giao diện với các phương thức đó.
raffian

1
@raffian, bạn có nghĩa là một giao diện được thực hiện bởi đối tượng trải qua quá trình tuần tự hóa và giải tuần tự hóa, hoặc bởi đối tượng chịu trách nhiệm quản lý quy trình? Các từ khóa tôi muốn đề xuất lần lượt là "Nối tiếp" và "Định dạng"; trang trí với Ithay đổi hàng đầu , viết hoa, và như vậy khi cần thiết.
Jeffrey Hantin

@JeffreyHantin Một đối tượng chịu trách nhiệm quản lý quy trình là điều tôi muốn nói; Bây giờ tôi đang sử dụng ISerializer, nhưng điều đó chỉ đúng một nửa :)
raffian

6
@raffian trong viễn thông, chúng tôi gọi một thành phần nối tiếp và giải tuần tự hóa một "SerDes" hoặc "serdes", thường được phát âm là sir-dez hoặc sir-deez tùy theo sở thích. Tôi cho rằng nó tương tự như "modem" (tức là "Bộ điều biến-Bộ giải mã") trong cấu trúc của nó.
davidA

2
@naki nó là toàn ngành - nếu bạn nhìn vào các bảng dữ liệu tốc độ cao, họ sẽ đề cập đến chức năng SERDES, mặc dù chúng đều khá hiện đại, trở lại những năm 1990. Google NGrams cho thấy nó trở nên phổ biến hơn vào những năm 1980, mặc dù tôi đã tìm thấy một ví dụ trong bảng dữ liệu của IBM từ năm 1970
davidA

208

Cả hai đều làm một điểm chung - đó là tuần tự hóa một Object. Tuần tự hóa được sử dụng để chuyển đối tượng hoặc lưu trữ chúng. Nhưng:

  • Tuần tự hóa: Khi bạn tuần tự hóa một đối tượng, chỉ có dữ liệu thành viên trong đối tượng đó được ghi vào luồng byte; không phải là mã thực sự thực hiện đối tượng.
  • Marshalling: Thuật ngữ Marshalling được sử dụng khi chúng ta nói về việc truyền Object cho các đối tượng ở xa (RMI) . Trong Marshalling Object được tuần tự hóa (dữ liệu thành viên được tuần tự hóa) + Codebase được đính kèm.

Vì vậy, serialization là một phần của Marshalling.

CodeBase là thông tin cho người nhận đối tượng biết nơi triển khai đối tượng này có thể được tìm thấy. Bất kỳ chương trình nào nghĩ rằng nó có thể chuyển một đối tượng sang một chương trình khác mà trước đây không thấy nó phải đặt cơ sở mã, để người nhận có thể biết nơi tải mã từ đó, nếu nó không có sẵn mã cục bộ. Người nhận sẽ, sau khi giải tuần tự hóa đối tượng, lấy mã cơ sở từ nó và tải mã từ vị trí đó.


45
+1 để xác định CodeBase có nghĩa là gì trong bối cảnh này
Omar Salem

2
Marshẩy mà không tuần tự hóa xảy ra. Xem Swing's invokeAndWaitand Forms's Invoke, sắp xếp một cuộc gọi đồng bộ đến luồng UI mà không liên quan đến tuần tự hóa.
Jeffrey Hantin

2
"Không phải mã thực sự thực hiện đối tượng": Liệu nó có nghĩa là các phương thức lớp? hoặc điều này có nghĩa là gì. Bạn có thể vui lòng giải thích.
Vishal Anand

2
Ý bạn là the implementation of this objectgì Bạn có thể cho một ví dụ cụ thể về SerializationMarshalling?
Simin Jie

Marshalling mà không tuần tự hóa xảy ra trong một số ngữ cảnh, chẳng hạn như khi một lệnh gọi hàm chuyển luồng điều khiển giữa các mô hình luồng (ví dụ, giữa một nhóm luồng chia sẻ và thư viện luồng đơn được ghim) trong một quy trình. Đó là lý do tại sao tôi nói chúng đồng nghĩa lỏng lẻo trong bối cảnh của RPC .
Jeffrey Hantin

94

Từ bài viết Wikipedia của Marshalling (khoa học máy tính) :

Thuật ngữ "soái ca" được coi là đồng nghĩa với "tuần tự hóa" trong thư viện chuẩn Python 1 , nhưng các thuật ngữ này không đồng nghĩa trong RFC 2713 liên quan đến Java:

Để "soái ca" một đối tượng có nghĩa là ghi lại trạng thái và cơ sở mã của nó theo cách mà khi đối tượng được sắp xếp là "không được sắp xếp", có thể lấy một bản sao của đối tượng ban đầu, có thể bằng cách tự động tải các định nghĩa lớp của đối tượng. Bạn có thể sắp xếp bất kỳ đối tượng nào là tuần tự hóa hoặc từ xa. Marshalling giống như tuần tự hóa, ngoại trừ marshalling cũng ghi lại các cơ sở mã. Marshalling khác với tuần tự hóa trong đó marshalling đối xử đặc biệt với các đối tượng từ xa. (RFC 2713)

Để "tuần tự hóa" một đối tượng có nghĩa là chuyển đổi trạng thái của nó thành một luồng byte theo cách mà luồng byte có thể được chuyển đổi trở lại thành một bản sao của đối tượng.

Vì vậy, marshalling cũng lưu mã cơ sở của một đối tượng trong luồng byte ngoài trạng thái của nó.


1
Bạn có nghĩa là một Đối tượng, nếu không được xác thực, chỉ có thể có trạng thái, sẽ không có bất kỳ cơ sở mã nào, nghĩa là không có chức năng nào của nó có thể được gọi, nó chỉ là một kiểu dữ liệu có cấu trúc. Và, nếu cùng một đối tượng được sắp xếp lại thì nó sẽ có cơ sở mã cùng với cấu trúc và một khi có thể gọi các chức năng của nó?
bjan

11
"Codebase" không thực sự có nghĩa là "Mã". Từ "Cách thức hoạt động của Codebase" ( goo.gl/VOM2Ym ) Codebase, khá đơn giản, cách các chương trình sử dụng ngữ nghĩa của RMI về tải lớp từ xa tìm các lớp mới. Khi người gửi của một đối tượng tuần tự hóa đối tượng đó để truyền đến một JVM khác, nó sẽ chú thích luồng byte được tuần tự hóa với thông tin được gọi là codebase. Thông tin này cho người nhận biết nơi thực hiện đối tượng này có thể được tìm thấy. Thông tin thực tế được lưu trữ trong chú thích cơ sở mã là một danh sách các URL mà từ đó tệp lớp cho đối tượng cần thiết có thể được tải xuống.
Giuseppe Bertone

2
@Neurone Định nghĩa đó là dành riêng cho Jini và RMI. "Codebase" là một thuật ngữ chung. vi.wikipedia.org/wiki/Codebase
Bill the Lizard

2
@BilltheLizard Vâng, nhưng vì bạn đang nói về việc sắp xếp thứ tự trong Java, nên đã sai khi nói rằng sự khác biệt giữa tuần tự hóa và sắp xếp thứ tự là "marshalling lưu mã của đối tượng ngoài trạng thái của nó", và nó dẫn đến câu hỏi của bjan. Marshalling lưu "codebase" ngoài trạng thái đối tượng.
Giuseppe Bertone

19

Tôi nghĩ rằng sự khác biệt chính là Marshalling được cho là cũng liên quan đến cơ sở mã. Nói cách khác, bạn sẽ không thể sắp xếp và sắp xếp một đối tượng thành một thể hiện tương đương trạng thái của một lớp khác. .

Tuần tự hóa chỉ có nghĩa là bạn có thể lưu trữ đối tượng và lấy lại trạng thái tương đương, ngay cả khi nó là một thể hiện của một lớp khác.

Điều đó đang được nói, chúng thường là từ đồng nghĩa.


2
Bạn có nghĩa là một Đối tượng, nếu không được xác thực, chỉ có thể có trạng thái, sẽ không có bất kỳ cơ sở mã nào, nghĩa là không có chức năng nào của nó có thể được gọi, nó chỉ là một kiểu dữ liệu có cấu trúc. Và, nếu cùng một đối tượng được sắp xếp lại thì nó sẽ có cơ sở mã cùng với cấu trúc và người ta có thể gọi các chức năng của nó không?
bjan

18

Marshaling đề cập đến việc chuyển đổi chữ ký và tham số của hàm thành một mảng byte đơn. Cụ thể cho mục đích của RPC.

Tuần tự hóa thường đề cập đến việc chuyển đổi toàn bộ cây đối tượng / đối tượng thành một mảng byte Marshaling sẽ tuần tự hóa các tham số đối tượng để thêm chúng vào tin nhắn và truyền nó qua mạng. * Tuần tự hóa cũng có thể được sử dụng để lưu trữ vào đĩa. *


11

Marshalling là quy tắc để báo cho trình biên dịch biết dữ liệu sẽ được biểu diễn trên môi trường / hệ thống khác như thế nào; Ví dụ;

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

như bạn có thể thấy hai giá trị chuỗi khác nhau được biểu diễn dưới dạng các loại giá trị khác nhau.

Tuần tự hóa sẽ chỉ chuyển đổi nội dung đối tượng, không đại diện (sẽ giữ nguyên) và tuân theo các quy tắc tuần tự hóa, (những gì cần xuất hoặc không). Ví dụ: các giá trị riêng tư sẽ không được tuần tự hóa, các giá trị công khai có và cấu trúc đối tượng sẽ giữ nguyên.


7

Dưới đây là ví dụ cụ thể hơn về cả hai:

Ví dụ nối tiếp:

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

Trong tuần tự hóa, dữ liệu được làm phẳng theo cách có thể được lưu trữ và không được làm phẳng sau này.

Trình diễn 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";
}

(Thống chếDemo.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);    
}

Trong đầm lầy, dữ liệu không nhất thiết phải được làm phẳng, nhưng nó cần phải được chuyển đổi sang một đại diện khác. tất cả các vai diễn đều là soái ca, nhưng không phải tất cả các diễn viên đều là đúc.

Marshaling không yêu cầu phân bổ động để được tham gia, nó cũng có thể chỉ là sự chuyển đổi giữa các cấu trúc. Ví dụ: bạn có thể có một cặp, nhưng hàm dự kiến ​​các phần tử thứ nhất và thứ hai sẽ khác nhau; bạn truyền / memcpy một cặp cho người khác sẽ không thực hiện công việc vì fst và snd sẽ bị lật.

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

Khái niệm về đầm lầy trở nên đặc biệt quan trọng khi bạn bắt đầu giao dịch với các hiệp hội được gắn thẻ thuộc nhiều loại. Ví dụ: bạn có thể gặp khó khăn khi có một công cụ JavaScript để in "chuỗi c" cho bạn, nhưng bạn có thể yêu cầu nó in một chuỗi c được bao bọc cho bạn. Hoặc nếu bạn muốn in một chuỗi từ thời gian chạy JavaScript trong thời gian chạy Lua hoặc Python. Chúng là tất cả các chuỗi, nhưng thường sẽ không hòa hợp với nhau mà không có sự sắp xếp.

Một sự phiền toái mà tôi đã gặp gần đây là mảng JScript sắp xếp thành C # là "__ComObject" và không có cách nào được ghi lại để chơi với đối tượng này. Tôi có thể tìm thấy địa chỉ của nó, nhưng tôi thực sự không biết gì về nó, vì vậy cách duy nhất để thực sự tìm ra nó là chọc vào nó bằng mọi cách có thể và hy vọng tìm thấy thông tin hữu ích về nó. Vì vậy, việc tạo một đối tượng mới với giao diện thân thiện hơn như Scripting.Dixi trở nên dễ dàng hơn, sao chép dữ liệu từ đối tượng mảng JScript vào đó và chuyển đối tượng đó sang C # thay vì mảng mặc định của JScript.

test.js:

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

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

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

ở trên in "__ComObject", phần nào của hộp đen theo quan điểm của C #.

Một khái niệm thú vị khác là bạn có thể hiểu cách viết mã và một máy tính biết cách thực hiện các hướng dẫn, vì vậy với tư cách là một lập trình viên, bạn đang thực hiện một cách hiệu quả khái niệm về những gì bạn muốn máy tính thực hiện từ bộ não của bạn đến chương trình hình ảnh. Nếu chúng ta có đủ soái ca tốt, chúng ta có thể nghĩ về những gì chúng ta muốn làm / thay đổi, và chương trình sẽ thay đổi theo cách đó mà không cần gõ trên bàn phím. Vì vậy, nếu bạn có cách lưu trữ tất cả các thay đổi vật lý trong não trong vài giây khi bạn thực sự muốn viết dấu chấm phẩy, bạn có thể sắp xếp dữ liệu đó thành tín hiệu để in dấu chấm phẩy, nhưng đó là một điều cực kỳ.


4

Marshalling thường là giữa các quá trình liên quan tương đối chặt chẽ; tuần tự hóa không nhất thiết phải có kỳ vọng đó. Vì vậy, khi sắp xếp dữ liệu giữa các quy trình, chẳng hạn, bạn có thể chỉ muốn gửi TÀI LIỆU THAM KHẢO để phục hồi dữ liệu đắt tiền, trong khi với việc tuần tự hóa, bạn muốn lưu lại tất cả, để tạo lại chính xác đối tượng khi được khử lưu trữ.


4

Sự hiểu biết của tôi về marshalling khác với các câu trả lời khác.

Tuần tự hóa:

Để sản xuất hoặc bù nước một phiên bản định dạng dây của biểu đồ đối tượng sử dụng quy ước.

Marshalling:

Để sản xuất hoặc bù nước một phiên bản định dạng dây của biểu đồ đối tượng bằng cách sử dụng tệp ánh xạ, để kết quả có thể được tùy chỉnh. Công cụ có thể bắt đầu bằng cách tuân thủ một quy ước, nhưng sự khác biệt quan trọng là khả năng tùy chỉnh kết quả.

Hợp đồng phát triển đầu tiên:

Marshalling là quan trọng trong bối cảnh phát triển hợp đồng đầu tiên.

  • Có thể thay đổi biểu đồ đối tượng bên trong, trong khi vẫn giữ giao diện bên ngoài ổn định theo thời gian. Bằng cách này, tất cả các thuê bao dịch vụ sẽ không phải sửa đổi cho mọi thay đổi nhỏ.
  • Có thể ánh xạ các kết quả trên các ngôn ngữ khác nhau. Ví dụ: từ quy ước tên thuộc tính của một ngôn ngữ ('property_name') sang ngôn ngữ khác ('propertyName').

1
//, Tôi có thể biết thêm về những gì, cụ thể, "bù nước" nghĩa là gì, trong câu trả lời ở đây, @JasperBlues? Tôi đoán nó không chỉ dành cho thực phẩm Phi hành gia.
Nathan Basan

@NathanBasan theo câu trả lời này - stackoverflow.com/a/6991192/5101816 - định nghĩa của (re) hydrating chứa trong các từ sau: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

Khái niệm cơ bản trước

Luồng Byte - Luồng là chuỗi dữ liệu. Luồng đầu vào - đọc dữ liệu từ nguồn. Luồng đầu ra - ghi dữ liệu vào trạng thái khử. Luồng Byte Java được sử dụng để thực hiện byte đầu vào / đầu ra theo byte (8 bit mỗi lần). Một luồng byte phù hợp để xử lý dữ liệu thô như các tệp nhị phân. Luồng ký tự Java được sử dụng để thực hiện 2 byte đầu vào / đầu ra cùng một lúc, bởi vì các ký tự được lưu trữ bằng cách sử dụng các quy ước Unicode trong Java với 2 byte cho mỗi ký tự. Luồng ký tự rất hữu ích khi chúng ta xử lý (đọc / ghi) tệp văn bản.

RMI (Gọi phương thức từ xa) - API cung cấp cơ chế tạo ứng dụng phân tán trong java. RMI cho phép một đối tượng gọi các phương thức trên một đối tượng đang chạy trong một JVM khác.


Cả serializationMarshalling đều được sử dụng một cách lỏng lẻo như các từ đồng nghĩa. Dưới đây là một vài sự khác biệt.

Tuần tự hóa - Các thành viên dữ liệu của một đối tượng được ghi vào dạng nhị phân hoặc Byte Stream (và sau đó có thể được ghi vào tệp / bộ nhớ / cơ sở dữ liệu, v.v.). Không có thông tin nào về kiểu dữ liệu có thể được giữ lại sau khi các thành viên dữ liệu đối tượng được ghi vào dạng nhị phân.

nhập mô tả hình ảnh ở đây

Marshalling - Object được tuần tự hóa (theo luồng byte ở định dạng nhị phân) với kiểu dữ liệu + Codebase được đính kèm và sau đó được truyền Remote Object (RMI) . Marshalling sẽ biến kiểu dữ liệu thành quy ước đặt tên được xác định trước để có thể được xây dựng lại theo kiểu dữ liệu ban đầu. nhập mô tả hình ảnh ở đây

Vì vậy, serialization là một phần của Marshalling.

CodeBase là thông tin cho người nhận đối tượng biết nơi triển khai đối tượng này có thể được tìm thấy. Bất kỳ chương trình nào nghĩ rằng nó có thể chuyển một đối tượng sang một chương trình khác mà trước đây không thấy nó phải đặt cơ sở mã, để người nhận có thể biết nơi tải mã từ đó, nếu nó không có sẵn mã cục bộ. Người nhận sẽ, sau khi giải tuần tự hóa đối tượng, lấy mã cơ sở từ nó và tải mã từ vị trí đó. (Sao chép từ câu trả lời @Nasir)

Tuần tự hóa gần giống như một bãi chứa bộ nhớ ngu ngốc của bộ nhớ được sử dụng bởi các đối tượng, trong khi Marshalling lưu trữ thông tin về các kiểu dữ liệu tùy chỉnh.

Theo một cách nào đó, Tuần tự hóa thực hiện việc sắp xếp theo thứ tự với giá trị truyền qua bởi vì không có thông tin nào về kiểu dữ liệu được truyền, chỉ có dạng nguyên thủy được truyền vào luồng byte.

Tuần tự hóa có thể có một số vấn đề liên quan đến endian lớn, endian nhỏ nếu luồng truyền từ hệ điều hành này sang hệ điều hành khác nếu hệ điều hành khác nhau có các phương tiện khác nhau để biểu thị cùng một dữ liệu. Mặt khác, marshalling là hoàn toàn tốt để di chuyển giữa các hệ điều hành vì kết quả là một đại diện cấp cao hơn.


1

Marshaling thực sự sử dụng quá trình Tuần tự hóa nhưng sự khác biệt chính là nó trong Tuần tự hóa chỉ các thành viên dữ liệu và bản thân đối tượng được tuần tự hóa không phải chữ ký mà trong cơ sở mã Marshalling Object + (triển khai của nó) cũng sẽ được chuyển đổi thành byte.

Marshalling là quá trình chuyển đổi đối tượng java thành các đối tượng xml bằng JAXB để có thể sử dụng nó trong các dịch vụ web.


0

Hãy nghĩ về chúng như những từ đồng nghĩa, cả hai đều có một nhà sản xuất gửi công cụ đến người tiêu dùng ... Trong các trường cuối của các thể hiện được ghi vào một luồng byte và đầu kia sẽ ngược lại và ngược lại với cùng một thể hiện.

NB - java RMI cũng chứa hỗ trợ vận chuyển các lớp bị thiếu từ người nhận ...

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.