有没有办法在不使用库的情况下序列化C ++类?

时间:2015-12-17 19:01:25

标签: c++ sockets networking serialization tcp

我会尽量保持简洁和具体。我正在开发一个复制文件的项目,然后创建它的精确副本。我想改进这个项目,以便它在服务器上复制一个文件,并将这些数据发送到客户端,然后客户端在本地机器上重新创建该文件。我使用Winsock设置了我的客户端/服务器,并且我能够使用TCP套接字在两者之间发送char *。我的问题是......将所有这些类数据拟合成char *。我假设序列化是最好的方法,但是,我希望尽可能简化代码,如果可能的话,非常希望不再使用这个特定项目的库。

这是我实际保存文件的代码: H:

#pragma once

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

class SaveFile{
private:
   streampos fileSize;//streampos data type holds current position of the buffer pointer or file pointer
   char* memBlock;
   string fileName;
public:
   SaveFile();
   ~SaveFile();

   streampos getSize();
   char* getMemBlock();

};

CPP:

#include <iostream>
#include "SaveFile.h"

SaveFile::SaveFile(){//default constructor
   cout << "Please enter file directory: ";
   cin >> fileName;

   //ios::ate means that the get pointer will be positioned at end of the file
   ifstream file(fileName, ios::in|ios::binary|ios::ate);

   if (file.is_open()){
         fileSize = file.tellg();//because get pointer is at end of file, tellg will return size of file in question
         memBlock = new char[fileSize];//allocating memory for the file

         file.seekg(0, ios::beg);//return get position to beginning of file
         file.read(memBlock, fileSize);//read file into memBlock variable
         file.close();//close file

         //default destructor will take care of cleanup
   }

}

SaveFile::~SaveFile(){}//default destructor

streampos SaveFile::getSize(){
   return fileSize;
}

char* SaveFile::getMemBlock(){
   return memBlock;
}

以下是重建文件的代码: H:

#pragma once

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

class SaveFile{
private:
   streampos fileSize;//streampos data type holds current position of the buffer pointer or file pointer
   char* memBlock;
   string fileName;
public:
   SaveFile();
   ~SaveFile();

   streampos getSize();
   char* getMemBlock();

};

CPP:

#include <iostream>
#include "WriteFile.h"

WriteFile::WriteFile(SaveFile sf){
   cout << "Please enter new file name: ";
   cin >> fileName;
   ofstream file(fileName, ios::out|ios::binary);
   file.write(sf.getMemBlock(), sf.getSize());
   file.close();
}

WriteFile::~WriteFile(){}

此代码的一个示例是:

#include "SaveFile.h"
#include "WriteFile.h"

int main(){
    SaveFile s;
    WriteFile w(s);
}

所以我的目标是以某种方式将SaveFile类的内容保存到char *,然后通过TCP套接字将其传输到另一台机器,然后将该char *转换回SaveFile对象,并将其传递给WriteFile这样它就可以重新创建有问题的文件。

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:1)

是的,您可以构建自己的序列化过程。

首先,要了解您的类或结构的字段之间可能存在填充。您可能不希望按原样编写结构内容。例如,您可能希望将数据打包到缓冲区中。

其次,需要区别对待可变长度字段。字符数组的指针就是一个例子。通常写入长度后跟内容。

非POD类型无法直接写入或读取。例如,std::string类。字符串类有一些成员数据,但通常,字符串内容在其他地方(如在动态内存中)。

我建议为每个对象实现以下方法:

  • 缓冲区中的字节大小 - 返回缓冲区中的字节数 这个对象占据了。
  • 从缓冲区加载 - 从指向缓冲区的指针加载其内容 按大小递增指针。
  • 写入缓冲区 - 通过指针将其内容存储到缓冲区 更新指针。

过程:

  1. 确定对象缓冲区中的字节大小
  2. 分配缓冲区
  3. 使用&#34;写入缓冲区&#34;写入缓冲区。方法
  4. 阻止将缓冲区写入文件或设备。