সি ++ তে কোনও শ্রেণিকে সিরিয়ালাইজ করা এবং ডিজাইরাইজ করা সম্ভব?


138

সি ++ তে কোনও শ্রেণিকে সিরিয়ালাইজ করা এবং ডিজাইরাইজ করা সম্ভব?

আমি এখন 3 বছর ধরে জাভা ব্যবহার করে আসছি, এবং সিরিয়ালাইজেশন / ডিসরিয়ালাইজেশন সেই ভাষায় মোটামুটি তুচ্ছ। সি ++ এর কি একই বৈশিষ্ট্য রয়েছে? দেশীয় গ্রন্থাগারগুলি রয়েছে যা সিরিয়ালাইজেশন পরিচালনা করে?

একটি উদাহরণ সহায়ক হবে।


2
আপনি "নেটিভ" বলতে যা বোঝায় তা নিশ্চিত নন, আপনি কি নেটিভ সি ++ (বুস্ট.সরিয়ালাইজেশন এর মতো) বলতে চান? আপনি কি কেবল সি ++ স্ট্যান্ডার্ড লাইব্রেরি ব্যবহার করছেন? আপনি অন্য কিছু বোঝাতে চান?
jwfearn

1
মানে "বাহ্যিক সফ্টওয়্যার-লাইব্রেরি নয়" এবং দুঃখিত আমার ইংরেজি খুব ভাল নয়: এস। আমি আর্জেন্টিনা থেকে আছি
আগুস্তি-এন

3
কোনও বস্তুর সিরিয়ালাইজ করার কোনও দেশীয় উপায় নেই (আপনি এখনও একটি পিওডি থেকে বাইনারি ডেটা ফেলে দিতে পারেন, তবে আপনি যা চান তা পাবেন না)। তবুও, বুস্ট, "অভ্যন্তরীণ গ্রন্থাগার" না হলেও এটি প্রথম বাইরের পাঠাগার যা আপনার সংকলকটিতে যুক্ত করার কথা বিবেচনা করা উচিত।
বুস্টটি

উত্তর:


95

Boost::serializationগ্রন্থাগার এই বরং এইরূপ সূচারূভাবে পরিচালনা করে। আমি এটি বেশ কয়েকটি প্রকল্পে ব্যবহার করেছি। এখানে একটি উদাহরণ প্রোগ্রাম রয়েছে, এটি কীভাবে ব্যবহার করবেন তা দেখানো হচ্ছে

এটি করার একমাত্র দেশীয় উপায় হ'ল স্ট্রিম ব্যবহার করা। এটি মূলত সমস্ত Boost::serializationগ্রন্থাগারই করে, এটি পাঠ্যের মতো বিন্যাসে অবজেক্ট লিখতে এবং একই ফর্ম্যাট থেকে সেগুলি পড়ার জন্য একটি কাঠামো স্থাপন করে স্ট্রিম পদ্ধতিটি প্রসারিত করে।

অন্তর্নির্মিত প্রকারের জন্য, বা আপনার নিজস্ব প্রকারের সাথে operator<<এবং operator>>সঠিকভাবে সংজ্ঞায়িত করা, এটি মোটামুটি সহজ; দেখতে সি ++ প্রায়শই জিজ্ঞাসিত প্রশ্নাবলী আরও তথ্যের জন্য।


আমার কাছে মনে হয় যে উত্সাহ :: সিরিয়ালাইজেশনের জন্য কলারটির প্রয়োজন যাতে অবজেক্টগুলি রচনা ও পঠন করা হয় সেদিকে নজর রাখে। এটা কি ঠিক? সুতরাং যদি কোনও প্রোগ্রামের সংস্করণগুলির মধ্যে দুটি ক্ষেত্রের ক্রমানুসারে পরিবর্তন হয় তবে আমাদের বেমানানতা রয়েছে। এটা কী ঠিক?
অগ্নেল কুরিয়ান

1
এটি সম্ভবত বুস্ট :: সিরিয়ালাইজেশন কোড নয়, ক্রমিক ক্রিয়াকলাপের কারণে হবে।
হেড গীক

1
@ 0xDEADBEEF: বাইনারি_ (i | o) সংরক্ষণাগার ব্যবহার করার পরে সম্ভবত এটি সুখী হবে, যা এন্ডিয়ান-নেসের মতো অন্যান্য "সমস্যা" উপস্থাপন করে। পাঠ্য_ (i | o) সংরক্ষণাগারটি চেষ্টা করে দেখুন, এটি আরও প্ল্যাটফর্ম অজিনস্টিক।
Ela782

2
একটি নির্দিষ্ট ফ্রেমওয়ার্ক / গ্রন্থাগার সমাধানের গ্রহণযোগ্য উত্তর হওয়া উচিত নয়।
Andrea

3
@ আন্ড্রেয়া: বুস্ট গ্রন্থাগারটি একটি বিশেষ ক্ষেত্রে। সি ++ ১১ টি চূড়ান্ত না হওয়া অবধি আধুনিক সি ++ কোডটি লেখা ছাড়া এটি অসম্ভব, সুতরাং এটি একটি পৃথক লাইব্রেরির চেয়ে গৌণ এসটিএলের কাছাকাছি ছিল।
হেড গিক

52

আমি বুঝতে পারছি এই একটি পুরানো পোস্টে কিন্তু এটা প্রথম যে আসে যখন অনুসন্ধানের জন্য এক c++ serialization

আমি সিরিয়ালের দিকে নজর রাখার জন্য সি ++ 11 এ অ্যাক্সেস থাকা যে কোনও ব্যক্তিকে উত্সাহিত করি , সিরিয়ালাইজেশনের জন্য সি ++ 11 শিরোনামের কেবল গ্রন্থাগার যা বাইনারি, জেএসএন এবং বাক্সের বাইরে এক্সএমএল সমর্থন করে। সিরিয়ালটি প্রসারিত এবং সহজে ব্যবহারের জন্য ডিজাইন করা হয়েছিল এবং এটি বুস্টের সাথে অনুরূপ সিনট্যাক্স রয়েছে।


4
সিরিয়াল সম্পর্কে ভাল জিনিস হ'ল উত্সাহের বিপরীতে এটির ন্যূনতম মেটাডেটা (প্রায় কোনওই নয়)। বুস্ট :: সিরিয়ালাইজেশন সত্যিই বিরক্তিকর হয়ে ওঠে যখনই আপনি যখন কোনও সংরক্ষণাগারটি খোলেন, এটি স্ট্রিমের কাছে তার lib সংস্করণটি লিখে দেয় যা কোনও ফাইলকে সংযুক্তি অসম্ভব করে তোলে।
সাইবারস্নপি

@ সাইবারস্নুপি - একটি সংরক্ষণাগার তৈরি হওয়ার সময় এই বৈশিষ্ট্যটি দমন করার জন্য একটি পতাকা রয়েছে - অবশ্যই সংরক্ষণাগারটি পড়ার সময় আপনাকে এটি মনে রাখতে হবে।
রবার্ট রামে

16

বুস্ট একটি ভাল পরামর্শ। তবে আপনি যদি নিজের রোল করতে চান তবে এটি এতটা কঠিন নয়।

মূলত আপনার কেবল অবজেক্টের গ্রাফ তৈরির একটি উপায় প্রয়োজন এবং তারপরে এগুলি কিছু কাঠামোগত স্টোরেজ ফর্ম্যাটে আউটপুট করতে (জেএসওএন, এক্সএমএল, ওয়াইএএমএল, যাই হোক না কেন)। গ্রাফটি তৈরি করা তত সরল একটি চিহ্নিত পুনরাবৃত্তাকারী শালীন অবজেক্ট অ্যালগরিদমকে ব্যবহার করা এবং তারপরে সমস্ত চিহ্নিত বস্তুর আউটপুট।

আমি একটি নিবন্ধ লিখেছিলাম একটি প্রাথমিক (তবে এখনও শক্তিশালী) সিরিয়ালাইজেশন সিস্টেমকে বর্ণনা করে। আপনি খুঁজে পেতে পারেন এটা আকর্ষণীয়: SQLite একটি অন-ডিস্ক ফাইল ফর্ম্যাট, পার্ট 2 হিসেবে ব্যবহার


14

"বিল্ট-ইন" লাইব্রেরি যতদূর যায়, <<এবং সেগুলি >>বিশেষভাবে সিরিয়ালকরণের জন্য সংরক্ষণ করা হয়েছে।

আপনি ওভাররাইড করা উচিত <<কিছু ধারাবাহিকতাতে প্রসঙ্গ (সাধারণত একটি আপনার বস্তুর আউটপুট iostream) এবং >>যে প্রসঙ্গ থেকে ডাটা ফিরে পড়তে। প্রতিটি অবজেক্ট তার সামগ্রিক শিশু বস্তুর আউটপুট দেওয়ার জন্য দায়ী।

আপনার অবজেক্ট গ্রাফটিতে কোনও চক্র না থাকায় এই পদ্ধতিটি এতক্ষণ দুর্দান্ত কাজ করে।

যদি এটি হয়, তবে আপনাকে সেই চক্রগুলি মোকাবেলা করতে একটি গ্রন্থাগার ব্যবহার করতে হবে।


3
অবশ্যই, এটি সঠিক হতে পারে না ... বাস্তবায়িত <<অপারেটরগুলি অবজেক্টগুলির মানব-পাঠযোগ্য পাঠ্য উপস্থাপনাগুলি মুদ্রণ করতে ব্যবহৃত হয়, যা সিরিয়ালায়নের জন্য আপনি যা চান তা প্রায়শই হয় না।
einpoklum

1
@ einpoklum সংজ্ঞা দেওয়ার পরিবর্তে << জেনেরিক জন্য ostream, একটি ফাইল স্ট্রীম জন্য এটি সংজ্ঞায়িত করার চেষ্টা করুন।
কারসিজেনিকেট

1
@ কারসিজেনিকেট: একটি লগ ফাইল যা মানব-পঠনযোগ্য পাঠ্য গ্রহণ করে তা একটি ফাইল স্ট্রিম।
einpoklum

1
@ আইনপোকলুম আপনার অর্থ কী তা আমি নিশ্চিত নই। ফ্র্যাঙ্ক ঠিক যদিও, এই অপারেটরগুলি সিরিয়ালাইজ করতে ব্যবহার করা যেতে পারে। আমি কেবল এগুলিকে ভেক্টরকে সিরিয়ালাইজ / ডিজাইরিয়ালাইজ করতে সংজ্ঞায়িত করেছি।
কার্সিজিনিট

2
আমি মনে করি ক্যাচটি এখানে রয়েছে " <<আপনার অবজেক্টটিকে কিছু সিরিয়ালের প্রেক্ষাপটে আউটপুট দেওয়ার জন্য ওভাররাইড করা উচিত ... প্রতিটি বস্তু এর আউটপুট দেওয়ার জন্য দায়ী ..." - প্রশ্নটি প্রতিটি বস্তুর জন্য কঠোরভাবে লেখার বিষয়টি এড়াতে কীভাবে হবে তা সম্পর্কে: কতটা পারে ভাষা বা গ্রন্থাগার সাহায্য?
শ্রীভাতসআর

14

আমি গুগল প্রোটোকল বাফারদের প্রস্তাব দিই । আমি একটি নতুন প্রকল্পে লাইব্রেরি ড্রাইভ পরীক্ষা করার সুযোগ পেয়েছিলাম এবং এটি ব্যবহার করা খুব সহজ। লাইব্রেরি কর্মক্ষমতা জন্য ভারী অনুকূলিত করা হয়।

প্রোটোবুফ এখানে বর্ণিত অন্যান্য সিরিয়ালাইজেশন সমাধানগুলির চেয়ে পৃথক যে এটি আপনার বস্তুগুলিকে সিরিয়ালাইজ করে না, বরং আপনার স্পেসিফিকেশন অনুসারে সিরিয়ালাইজেশন করা অবজেক্টগুলির কোড তৈরি করে।


2
এটি ব্যবহার করে আপনার 10-50MB আকারের আকারের অবজেক্টের অভিজ্ঞতা আছে? ডকুমেন্টেশন বলে মনে হচ্ছে প্রোটোকল বাফারগুলি আকারের এমবি সম্পর্কে অবজেক্টগুলির জন্য সবচেয়ে উপযুক্ত।
অগ্নেল কুরিয়ান



4

আপনি আমেফ প্রোটোকলটি পরীক্ষা করতে পারেন, আমেফের সি ++ এনকোডিংয়ের উদাহরণটি এমন হবে,

    //Create a new AMEF object
    AMEFObject *object = new AMEFObject();

    //Add a child string object
    object->addPacket("This is the Automated Message Exchange Format Object property!!","adasd");   

    //Add a child integer object
    object->addPacket(21213);

    //Add a child boolean object
    object->addPacket(true);

    AMEFObject *object2 = new AMEFObject();
    string j = "This is the property of a nested Automated Message Exchange Format Object";
    object2->addPacket(j);
    object2->addPacket(134123);
    object2->addPacket(false);

    //Add a child character object
    object2->addPacket('d');

    //Add a child AMEF Object
    object->addPacket(object2);

    //Encode the AMEF obejct
    string str = new AMEFEncoder()->encode(object,false);

জাভাতে ডিকোডিংয়ের মতো হবে,

    string arr = amef encoded byte array value;
    AMEFDecoder decoder = new AMEFDecoder()
    AMEFObject object1 = AMEFDecoder.decode(arr,true);

প্রোটোকল বাস্তবায়নে সি ++ এবং জাভা উভয়েরই কোডেক রয়েছে, আকর্ষণীয় অংশটি হ'ল নাম মান জোড় আকারে এটি অবজেক্ট শ্রেণির প্রতিনিধিত্ব ধরে রাখতে পারে, আমার শেষ প্রজেক্টে আমার অনুরূপ প্রোটোকল দরকার ছিল, যখন আমি ঘটনাক্রমে এই প্রোটোকলের উপর হোঁচট খেয়েছি, আসলে আমি ছিলাম আমার প্রয়োজনীয়তা অনুযায়ী বেস লাইব্রেরিটি পরিবর্তন করেছে। আশা করি এটি আপনাকে সহায়তা করবে।


3

আমি অন্যান্য পোস্টার দ্বারা বর্ণিত হিসাবে বুস্ট সিরিয়ালাইজেশন ব্যবহার করার পরামর্শ দিচ্ছি। এটি কীভাবে ব্যবহার করতে হয় সে সম্পর্কে একটি ভাল বিশদ টিউটোরিয়াল এখানে উত্সাহিত টিউটোরিয়ালগুলি সুন্দরভাবে পরিপূরক: http://www.ocoudert.com/blog/2011/07/09/a-practical-guide-to-c-seialization/


3

মিষ্টি পার্সিস্ট অন্য এক।

এক্সএমএল, জেএসএন, লুয়া এবং বাইনারি ফর্ম্যাটগুলিতে এবং স্ট্রিমগুলি থেকে সিরিয়ালাইজ করা সম্ভব।


সাইটটি নীচে নেমে গেছে বলে মনে হয়েছিল, আমি কেবল এই পুরানো রেপোটিই
জানুশ সাইফ

2

আমি অ্যাবস্ট্রাক্ট কারখানাগুলিতে সন্ধান করার পরামর্শ দিচ্ছি যা প্রায়শই সিরিয়ালাইজেশনের ভিত্তি হিসাবে ব্যবহৃত হয়

আমি সি ++ কারখানা সম্পর্কে আরও একটি এসও প্রশ্নের উত্তর দিয়েছি। নমনীয় কারখানাটি যদি আগ্রহী হয় তবে দয়া করে সেখানে দেখুন । আমি ম্যাক্রোগুলি ব্যবহার করতে ET ++ থেকে একটি পুরানো উপায় বর্ণনা করার চেষ্টা করি যা আমার পক্ষে দুর্দান্ত কাজ করেছে।

ET ++ পুরানো ম্যাক অ্যাপ্লিকেশনটিকে সি ++ এবং এক্স 11-তে পোর্ট করার একটি প্রকল্প ছিল। এর প্রয়াসে এরিক গামা ইত্যাদি ডিজাইন প্যাটার্নগুলি সম্পর্কে চিন্তাভাবনা শুরু করে । রানটাইম সময়ে সিরিয়ালাইজেশন এবং আত্মপরিমাণের জন্য ইটি ++ এ স্বয়ংক্রিয় উপায় রয়েছে।


0

আপনি যদি সহজ এবং সেরা পারফরম্যান্স চান এবং পশ্চাদপটে ডেটা সামঞ্জস্যতার বিষয়ে চিন্তা না করেন তবে এইচপিএস চেষ্টা করুন , এটি হালকা, বুস্ট ইত্যাদির চেয়ে অনেক দ্রুত এবং প্রোটোবুফ ইত্যাদির চেয়ে আরও সহজ use

উদাহরণ:

std::vector<int> data({22, 333, -4444});
std::string serialized = hps::serialize_to_string(data);
auto parsed = hps::parse_from_string<std::vector<int>>(serialized);

0

এখানে আমি নকিয়াছিলাম একটি সাধারণ সিরিয়ালাইজার লাইব্রেরি। এটি কেবল শিরোনাম, সি 11 এবং মৌলিক ধরণের সিরিয়ালাইজেশনের উদাহরণ রয়েছে। ক্লাসে মানচিত্রের জন্য এখানে একটি।

https://github.com/goblinhack/simple-c-plus-plus-serializer

#include "c_plus_plus_serializer.h"

class Custom {
public:
    int a;
    std::string b;
    std::vector c;

    friend std::ostream& operator<<(std::ostream &out, 
                                    Bits my)
    {
        out << bits(my.t.a) << bits(my.t.b) << bits(my.t.c);
        return (out);
    }

    friend std::istream& operator>>(std::istream &in, 
                                    Bits my)
    {
        in >> bits(my.t.a) >> bits(my.t.b) >> bits(my.t.c);
        return (in);
    }

    friend std::ostream& operator<<(std::ostream &out, 
                                    class Custom &my)
    {
        out << "a:" << my.a << " b:" << my.b;

        out << " c:[" << my.c.size() << " elems]:";
        for (auto v : my.c) {
            out << v << " ";
        }
        out << std::endl;

        return (out);
    }
};

static void save_map_key_string_value_custom (const std::string filename)
{
    std::cout << "save to " << filename << std::endl;
    std::ofstream out(filename, std::ios::binary );

    std::map< std::string, class Custom > m;

    auto c1 = Custom();
    c1.a = 1;
    c1.b = "hello";
    std::initializer_list L1 = {"vec-elem1", "vec-elem2"};
    std::vector l1(L1);
    c1.c = l1;

    auto c2 = Custom();
    c2.a = 2;
    c2.b = "there";
    std::initializer_list L2 = {"vec-elem3", "vec-elem4"};
    std::vector l2(L2);
    c2.c = l2;

    m.insert(std::make_pair(std::string("key1"), c1));
    m.insert(std::make_pair(std::string("key2"), c2));

    out << bits(m);
}

static void load_map_key_string_value_custom (const std::string filename)
{
    std::cout << "read from " << filename << std::endl;
    std::ifstream in(filename);

    std::map< std::string, class Custom > m;

    in >> bits(m);
    std::cout << std::endl;

    std::cout << "m = " << m.size() << " list-elems { " << std::endl;
    for (auto i : m) {
        std::cout << "    [" << i.first << "] = " << i.second;
    }
    std::cout << "}" << std::endl;
}

void map_custom_class_example (void)
{
    std::cout << "map key string, value class" << std::endl;
    std::cout << "============================" << std::endl;
    save_map_key_string_value_custom(std::string("map_of_custom_class.bin"));
    load_map_key_string_value_custom(std::string("map_of_custom_class.bin"));
    std::cout << std::endl;
}

আউটপুট:

map key string, value class
============================
save to map_of_custom_class.bin
read from map_of_custom_class.bin

m = 2 list-elems {
    [key1] = a:1 b:hello c:[2 elems]:vec-elem1 vec-elem2
    [key2] = a:2 b:there c:[2 elems]:vec-elem3 vec-elem4
}

0

সিরিয়ালাইজেশন প্রয়োগ করতে আমি নিম্নলিখিত টেমপ্লেটটি ব্যবহার করছি:

template <class T, class Mode = void> struct Serializer
{
    template <class OutputCharIterator>
    static void serializeImpl(const T &object, OutputCharIterator &&it)
    {
        object.template serializeThis<Mode>(it);
    }

    template <class InputCharIterator>
    static T deserializeImpl(InputCharIterator &&it, InputCharIterator &&end)
    {
        return T::template deserializeFrom<Mode>(it, end);
    }
};

template <class Mode = void, class T, class OutputCharIterator>
void serialize(const T &object, OutputCharIterator &&it)
{
    Serializer<T, Mode>::serializeImpl(object, it);
}

template <class T, class Mode = void, class InputCharIterator>
T deserialize(InputCharIterator &&it, InputCharIterator &&end)
{
    return Serializer<T, Mode>::deserializeImpl(it, end);
}

template <class Mode = void, class T, class InputCharIterator>
void deserialize(T &result, InputCharIterator &&it, InputCharIterator &&end)
{
    result = Serializer<T, Mode>::deserializeImpl(it, end);
}

Tআপনি যে ধরণের সিরিয়ালাইজ করতে চান তা এখানেMode হ'ল বিভিন্ন ধরণের সিরিয়ালাইজেশনের মধ্যে পার্থক্য করার জন্য একটি ডামি টাইপ, যেমন। একই পূর্ণসংখ্যাটি ছোট এন্ডিয়ান, বিগ এন্ডিয়ান, ভার্টিন্ট ইত্যাদি হিসাবে সিরিয়ালযুক্ত করা যায়

ডিফল্টরূপে Serializerবস্তুটির ক্রমিকায়িত হওয়ার জন্য প্রতিনিধিত্ব করে। অন্তর্নির্মিত জন্য আপনার একটি টেমপ্লেট বিশেষীকরণ করা উচিতSerializer

সুবিধা ফাংশন টেমপ্লেট এছাড়াও সরবরাহ করা হয়।

উদাহরণ স্বরূপ স্বাক্ষরিত পূর্ণসংখ্যার সামান্য এন্ডিয়ান সিরিয়ালাইজেশন:

struct LittleEndianMode
{
};

template <class T>
struct Serializer<
    T, std::enable_if_t<std::is_unsigned<T>::value, LittleEndianMode>>
{
    template <class InputCharIterator>
    static T deserializeImpl(InputCharIterator &&it, InputCharIterator &&end)
    {
        T res = 0;

        for (size_t i = 0; i < sizeof(T); i++)
        {
            if (it == end) break;
            res |= static_cast<T>(*it) << (CHAR_BIT * i);
            it++;
        }

        return res;
    }

    template <class OutputCharIterator>
    static void serializeImpl(T number, OutputCharIterator &&it)
    {
        for (size_t i = 0; i < sizeof(T); i++)
        {
            *it = (number >> (CHAR_BIT * i)) & 0xFF;
            it++;
        }
    }
};

তারপরে সিরিয়ালাইজ করতে:

std::vector<char> serialized;
uint32_t val = 42;
serialize<LittleEndianMode>(val, std::back_inserter(serialized));

Deserialize করতে:

uint32_t val;
deserialize(val, serialized.begin(), serialized.end());

বিমূর্ত পুনরুক্তি যুক্তির কারণে, এটি কোনও পুনরুক্তি (যেমন স্ট্রিম পুনরাবৃত্তকারী), পয়েন্টার ইত্যাদির সাথে কাজ করা উচিত should

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.