【Linux实验】2、对象的序列化

声明:内容是老师PPT里的,非我原创
序列化:将对象(所有的数据成员)变成一个字节序写入某个文件 反序列化:将某个文件里的字节序变成一个对象

版本一:将一个类的一个对象序列化到文件

demo.h

#include<iostream>
#include<fstream>
#include<string>
using namespace std;

class demo{
    private:
        int i;
    public:
        demo(){
            i=0;
        }

        demo(int j){
            i=j;
        }

        //序列化方法
        int Serialize(char* pBuffer){
            long length=sizeof(this);
            ofstream *o= new ofstream(pBuffer);
            o->write((char*)this,length);
            o->close();
            delete o;
            return 1;
        }

        //反序列化方法
        static demo Deserialize(const char* pBuffer){
            char buf[1000];
            ifstream is(pBuffer);
            is>>buf;
            demo *a = (demo*)buf;
            is.close();
            return (*a);
        }

        void f(){
            cout<<"i="<<this->i <<endl;
        }
};

main.cpp

#include "demo.h"

int main(){
    demo a(1);
    a.Serialize("data");
    demo b = demo::Deserialize("data");
    b.f();

    return 0;
}

运行示例:
在这里插入图片描述
执行main.cpp之后成功将demo类的实体a以二进制形式存入data文件中,并反序列化为实体b

版本二:将一个类的多个对象序列化到文件

思路:声明一个vector,循环序列化和反序列化
为什么要加#ifndef这位网友说得很好
在这里插入图片描述
示例:
在这里插入图片描述
在这里插入图片描述

A.h

#ifndef _A_H_
#define _A_H_

#include <iostream>
#include <fstream>
#include <string>

using  namespace std ;
class A{
private:
    int i;

public:
    A(){
        i = 0;
    }

    A(int j){
        i = j;
    }


    int Serialize(char* pBuffer){
        long length = sizeof(this);
        ofstream *o = new ofstream(pBuffer);
        o->write((char*)this, length);
        o->close();
        delete o;
        return 1;
    }

    static A Deserialize(const char* pBuffer){
        char buf[1000];
        ifstream is(pBuffer);
        is >> buf;
        A *a = (A*) buf;
        is.close();
        return (*a);
    }

    void f(){
        cout << "i = " << this->i << endl;
    }

    int GetObjSize(unsigned int * pObjSize){
        *pObjSize = 4;
        return 1;
    }

};
#endif

SerializerForAs.h

//
// Created by dj on 2018/10/26.
//

#include "A.h"
#include <iostream>
#include <fstream>
#include <vector>
#include <stdio.h>

using namespace std;

class SerializerForAs{

public:
    static int Serialize(const char* pFilePath, vector<A *>& v){
        FILE* fp = fopen(pFilePath, "w+");
        for(int i = 0; i < v.size(); i++){
            fwrite(v[i], sizeof(int), 1, fp);
        }
        fclose(fp);
        return 1;
    }

    static int Deserialize(const char* pFilePath, vector<A *>& v){
        FILE *fp = fopen(pFilePath, "r");
        for(int i = 0; i < v.size(); i++){
            fread(v[i], sizeof(int), 1, fp);
        }
        fclose(fp);
        return 1;
    }

};

main.cpp

#include "A.h"
#include <iostream>
#include <vector>
#include "SerializerForAs.h"

using namespace std;

int main(){
    A a1(100);
    A a2(200);

    vector<A *> v1;
    v1.push_back(&a1);
    v1.push_back(&a2);
    SerializerForAs::Serialize("data", v1);

    A a3;
    A a4;

    vector<A *> v2;
    v2.push_back(&a3);
    v2.push_back(&a4);
    SerializerForAs::Deserialize("data", v2);
    a3.f();
    a4.f();

}

在这里插入图片描述

版本三:将两个不同类的多个对象序列化到文件

思路:对象变成的字节流中,要有能够识别对象类型的信息
把一个类的对象和一个用来区别类种类的int字段封装在一个结构体内。

#include <iostream>
#include <stdio.h>
#include <fcntl.h>
#include <vector>

using namespace std;

class A{
    public:
    A(){
        i = 0;
    }

    A(int j){
        i = j;
    }

    void f(){
        cout << "i = " << i << endl;
    }

    public:
    bool Serialize(FILE *fp){
        if(fp == NULL)
            return false;
        fwrite(&i, sizeof(int), 1, fp);
        return true;
    }

    bool Deserialize(FILE *fp){
        if(fp == NULL)
            return false;
        fread(this, sizeof(int), 1, fp);
        return true;
    }
    private:
        int i;
};

class B{
    public:
    B(){
        i = 0;
        j = 0;
    }

    B(int k){
        i = k;
        j = k + 1;
    }

    bool Serialize(FILE* fp){
        if(fp == NULL)
            return false;
        fwrite(&i, sizeof(int), 1, fp);
        fwrite(&j, sizeof(int), 1, fp);
        return true;
    }

    bool Deserialize(FILE* fp){
        fread(&(this->i), sizeof(int), 1, fp);
        fread(&(this->j), sizeof(int), 1, fp);
        return true;
    }

    void f(){
        cout << "i = " << i << " , j = " << j << endl;
    }

    private:
        int i, j;

};

struct Serialized{
    int nType;
    void *pObj;
};

class Serializer{
    public:
        bool Serialize(const char* pFilePath, vector<Serialized>& v){
            FILE* fp = fopen(pFilePath, "w+");
            if(fp == NULL)
                return false;
            for(int i = 0; i < v.size(); i++){
                fwrite(&(v[i].nType), sizeof(int), 1, fp);
                if(0 == v[i].nType){
                    A *p = (A*)(v[i].pObj);
                    p->Serialize(fp);
                }else if(1 == v[i].nType){
                    B *p = (B*)(v[i].pObj);
                    p->Serialize(fp);
                }
            }
            fclose(fp);
        }

        bool Deserialize(const char *pFilePath, vector<Serialized> &v){
            FILE* fp = fopen(pFilePath, "r+");
            for(;;){
                int nType;
                int r = fread(&nType, sizeof(int), 1, fp);
                if(-1 == r || 0 == r)
                    break;
                if(0 == nType){
                    A *p;
                    p = new A();
                    p->Deserialize(fp);

                    Serialized s;
                    s.nType = nType;
                    s.pObj = p;
                    v.push_back(s);
                }else if(1 == nType){
                    B *p;
                    p = new B();
                    p -> Deserialize(fp);

                    Serialized s;
                    s.nType = nType;
                    s.pObj = p;
                    v.push_back(s);
                }
            }
            fclose(fp);
            return true;
        }
};

int main() {
    {
        {
            A a1(2);
            Serialized s1;
            s1.nType = 0;
            s1.pObj = &a1;

            B b1(3);
            Serialized s2;
            s2.nType = 1;
            s2.pObj = &b1;

            B b2(4);
            Serialized s3;
            s3.nType = 1;
            s3.pObj = &b2;

            A a2(5);
            Serialized s4;
            s4.nType = 0;
            s4.pObj = &a2;

            vector<Serialized> v;
            v.push_back(s1);
            v.push_back(s2);
            v.push_back(s3);
            v.push_back(s4);

            Serializer s;
            s.Serialize("data", v);
        }

        {
            Serializer s;
            vector<Serialized> v;
            s.Deserialize("data", v);

            for(int i = 0; i < v.size(); i++){
                if(v[i].nType == 0){
                    A *p = (A*)(v[i].pObj);
                    p->f();
                }else if(v[i].nType == 1){
                    B *p = (B*)(v[i].pObj);
                    p->f();
                }
            }
        }
        return 0;
    }
}

在这里插入图片描述

版本四:将三个不同类的多个对象序列化到文件

要求:当又有新的类的对象,需要序列化到文件时,不能修改已有的代码
采用面向对象的方法,查找变化点,抽象出需要进行序列化的基类

思路:申明一个接口,每一个需要序列化的对象都是接口的实现

#include <fcntl.h>
#include <iostream>
#include <vector>
#include <stdio.h>

class ILSerializable
{
public:
    virtual bool Serialize(FILE* fp) = 0;
    virtual ILSerializable* Deserialize(FILE* fp) = 0;
    virtual bool GetType(int& type) = 0;

public:
    ILSerializable()
    {
    }

    virtual ~ILSerializable()
    {
    }
};

class A : public ILSerializable
{
public:
    A()
    {
        i = 0;
    }

    explicit A(int j)
    {
        i = j;
    }

    virtual ~A()
    {
    }

public:
    void f()
    {
        std::cout << "in f(): " << i << std::endl;
    }

public:
    virtual bool GetType(int& type)
    {
        type = 0;
        return true;
    }

    virtual bool Serialize(FILE *fp){
        if(fp == NULL)
            return false;
        fwrite(&i, sizeof(int), 1, fp);
        return true;
    }

    virtual ILSerializable* Deserialize(FILE *fp){
        A *p = new A();
        fread(&(p->i), sizeof(int), 1, fp);
        return p;
    }

private:
    int i;
};

class B : public ILSerializable
{
public:
    B()
    {
        i = 0;
        j = 0;
    }

    explicit B(int k)
    {
        i = k;
        j = k + 1;
    }

    virtual ~B()
    {
    }

public:
    void f()
    {
        std::cout << "in f(): " << i << " " << j << std::endl;
    }

public:
    virtual bool GetType(int& type)
    {
        type = 1;
        return true;
    }

    virtual bool Serialize(FILE *fp)
    {
        if(fp == NULL)
            return false;
        fwrite(&i, sizeof(int), 1, fp);
        fwrite(&j, sizeof(int), 1, fp);
        return true;
    }

    virtual ILSerializable*  Deserialize(FILE* fp)
    {

        B *p = new B();
        fread(&(p->i), sizeof(int), 1, fp);
        fread(&(p->j), sizeof(int), 1, fp);
        return p;
    }

private:
    int i;
    int j;
};

class CLSerializer
{
public:
    bool Serialize(const char *pFilePath, std::vector<ILSerializable*>& v)
    {
        FILE* fp = fopen(pFilePath, "w+");
        if(fp == NULL)
            return false;
        for(int i = 0; i < v.size(); i++)
        {
            int type;
            v[i]->GetType(type);
            fwrite(&type, sizeof(int), 1, fp);
            v[i]->Serialize(fp);
        }
        fclose(fp);
        return true;
    }

    bool Deserialize(const char *pFilePath, std::vector<ILSerializable*>& v)
    {
        FILE* fp = fopen(pFilePath, "r+");
        if(fp == NULL)
            return false;
        for(;;)
        {
            int nType = -1;
            int r = fread(&nType, sizeof(int), 1, fp);

            int type;
            for(int i = 0; i < m_vSerialized.size(); i++)
            {
                m_vSerialized[i]->GetType(type);
                if(type == nType)
                {
                    ILSerializable *p = m_vSerialized[i]->Deserialize(fp);
                    if(p != NULL)
                        v.push_back(p);
                }
            }
            if(r == 0)
                break;
        }
        fclose(fp);
        return true;
    }
    void Register(ILSerializable *pSerialized)
    {
	m_vSerialized.push_back(pSerialized);
    }

private:
    std::vector<ILSerializable*> m_vSerialized;
};

int main()
{
    {
        A a1(2);
        B b1(3);
        B b2(4);
        A a2(5);

        std::vector<ILSerializable*> v;

        v.push_back(&a1);
        v.push_back(&b1);
        v.push_back(&b2);
        v.push_back(&a2);

        CLSerializer s;
        s.Serialize("data", v);
    }

    {
        CLSerializer s;
		A a;
		B b;
		s.Register(&a);
		s.Register(&b);

        std::vector<ILSerializable*> v;
        s.Deserialize("data", v);

        for(int i = 0; i < v.size(); i++)
        {
            A *p = dynamic_cast<A *>(v[i]);
            if(p != NULL)
                p->f();

            B *q = dynamic_cast<B *>(v[i]);
            if(q != NULL)
                q->f();
        }
    }

    return 0;
}


在这里插入图片描述

版本五:配置序列化位置

读取配置文件写的序列化路径,在config.txt里写明路径,则存的数据将到目标目录下
在这里插入图片描述
(文件夹要提前建好)

#include <fcntl.h>
#include <iostream>
#include <vector>
#include <stdio.h>
#include <string.h>

class ILSerializable
{
public:
    virtual bool Serialize(FILE* fp) = 0;
    virtual ILSerializable* Deserialize(FILE* fp) = 0;
    virtual bool GetType(int& type) = 0;

public:
    ILSerializable()
    {
    }

    virtual ~ILSerializable()
    {
    }
};

class A : public ILSerializable
{
public:
    A()
    {
        i = 0;
    }

    explicit A(int j)
    {
        i = j;
    }

    virtual ~A()
    {
    }

public:
    void f()
    {
        std::cout << "in f(): " << i << std::endl;
    }

public:
    virtual bool GetType(int& type)
    {
        type = 0;
        return true;
    }

    virtual bool Serialize(FILE *fp){
        if(fp == NULL)
            return false;
        fwrite(&i, sizeof(int), 1, fp);
        return true;
    }

    virtual ILSerializable* Deserialize(FILE *fp){
        A *p = new A();
        fread(&(p->i), sizeof(int), 1, fp);
        return p;
    }

private:
    int i;
};

class B : public ILSerializable
{
public:
    B()
    {
        i = 0;
        j = 0;
    }

    explicit B(int k)
    {
        i = k;
        j = k + 1;
    }

    virtual ~B()
    {
    }

public:
    void f()
    {
        std::cout << "in f(): " << i << " " << j << std::endl;
    }

public:
    virtual bool GetType(int& type)
    {
        type = 1;
        return true;
    }

    virtual bool Serialize(FILE *fp)
    {
        if(fp == NULL)
            return false;
        fwrite(&i, sizeof(int), 1, fp);
        fwrite(&j, sizeof(int), 1, fp);
        return true;
    }

    virtual ILSerializable*  Deserialize(FILE* fp)
    {

        B *p = new B();
        fread(&(p->i), sizeof(int), 1, fp);
        fread(&(p->j), sizeof(int), 1, fp);
        return p;
    }

private:
    int i;
    int j;
};

class CLSerializer
{
public:
    bool Serialize(const char *pFilePath, std::vector<ILSerializable*>& v)
    {
        FILE* fp = fopen(pFilePath, "w+");
        if(fp == NULL)
            return false;
        for(int i = 0; i < v.size(); i++)
        {
            int type;
            v[i]->GetType(type);
            fwrite(&type, sizeof(int), 1, fp);
            v[i]->Serialize(fp);
        }
        fclose(fp);
        return true;
    }

    bool Deserialize(const char *pFilePath, std::vector<ILSerializable*>& v)
    {
        FILE* fp = fopen(pFilePath, "r+");
        if(fp == NULL)
            return false;
        for(;;)
        {
            int nType = -1;
            int r = fread(&nType, sizeof(int), 1, fp);

            int type;
            for(int i = 0; i < m_vSerialized.size(); i++)
            {
                m_vSerialized[i]->GetType(type);
                if(type == nType)
                {
                    ILSerializable *p = m_vSerialized[i]->Deserialize(fp);
                    if(p != NULL)
                        v.push_back(p);
                }
            }
            if(r == 0)
                break;

        }
        fclose(fp);
        return true;
    }

    void Register(ILSerializable *pSerialized)
    {
        m_vSerialized.push_back(pSerialized);
    }

private:
    std::vector<ILSerializable*> m_vSerialized;
};

int main()
{
    FILE *fp = fopen("config.txt", "r+");
    char buf[100];
    int len;
    while(fgets(buf,100,fp) != NULL);
    {
        A a1(2);
        B b1(3);
        B b2(4);
        A a2(5);

        std::vector<ILSerializable*> v;

        v.push_back(&a1);
        v.push_back(&b1);
        v.push_back(&b2);
        v.push_back(&a2);

        CLSerializer s;
        s.Serialize(buf, v);
    }

    {
        CLSerializer s;
        A a;
        B b;
        s.Register(&a);
        s.Register(&b);

        std::vector<ILSerializable*> v;
        s.Deserialize(buf, v);

        for(int i = 0; i < v.size(); i++)
        {
            A *p = dynamic_cast<A *>(v[i]);
            if(p != NULL)
                p->f();

            B *q = dynamic_cast<B *>(v[i]);
            if(q != NULL)
                q->f();
        }
    }

    return 0;
}


循环读取config.txt中的文件路径,实现序列化和反序列化。
在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值