c++ - 有没有一种方法可以在不使用库的情况下序列化 C++ 类?

标签 c++ sockets networking serialization tcp

我会尽量保持简短和具体。我正在做一个复制文件的项目,然后创建它的精确拷贝。我想改进这个项目,以便它在服务器上复制一个文件,并将此数据发送到客户端,然后在本地计算机上重新创建该文件。我使用 Winsock 设置了客户端/服务器,并且能够使用 TCP 套接字在两者之间发送一个 char*。我的问题是......将所有此类数据放入一个 char* 中。我认为序列化是执行此操作的最佳方式,但是,我希望代码尽可能简单,并且如果可能的话,我非常希望消除对这个特定项目的库的使用。

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

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

这里是重建文件的代码: :

#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以便它可以重新创建有问题的文件。

非常感谢任何帮助!

最佳答案

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

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

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

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

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

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

过程:

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

关于c++ - 有没有一种方法可以在不使用库的情况下序列化 C++ 类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34342279/

相关文章:

C++11 基于范围的按值、引用和指针的自动 for 循环

c++ - 类型到值元函数可以用作 C++14 中的变量别名吗?

c - 在 C 中获取网页源代码的最有效方法是什么?

java - 本地网络中的android模拟器访问服务器

java - J2ME中如何实现线程超时?

c++ - 为什么使用 Visual Studio 6 for C++

c++ - 从 CLI C++ 项目引用非托管 C++ 项目

c# 测试服务器和客户端应用程序之间的带宽

c++ - send() 函数返回所需的更多字节 C++

sockets - 套接字编程 - 多人射击游戏服务器如何处理计时?