我有以下结构:
struct ArchiveTableEntry
{
uint32_t id;
char filename[MAX_FILENAME_LEN + 1];
uint32_t filename_crc32;
uint32_t real_data_size;
uint32_t block_data_size;
uint32_t data_crc32;
char data_md5_checksum[16];
uint64_t data_offset;
uint8_t flag;
};
在序列化后,我有很好的输出文件。 也可以从文件工作中加载。 我使用 memcpy 来执行序列化/反序列化,现在我的问题是:如何替换char filename [MAX_FILENAME_LEN + 1];通过std :: string,并保持序列化/反序列化工作,保存浪费的未使用字节。 谢谢!
答案 0 :(得分:3)
尽量避免将memcpy-ing用于指向序列化的指针。相反,请使用流。您甚至可以创建一个序列化任何类型数据的流类。接下来你只需添加<<和>>运算符到任何需要序列化的类。
#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
struct ArchiveTableEntry
{
uint32_t id;
std::string filename;
uint32_t filename_crc32;
uint32_t real_data_size;
uint32_t block_data_size;
uint32_t data_crc32;
char data_md5_checksum[16];
uint64_t data_offset;
uint8_t flag;
};
std::ostream& operator << (std::ostream& os, const ArchiveTableEntry entry)
{
return os << entry.id << entry.filename.size() << entry.filename
<< entry.filename_crc32 << entry.real_data_size << entry.block_data_size
<< entry.data_crc32 << entry.data_md5_checksum << entry.data_offset << entry.flag;
}
std::istream& operator >> (std::istream& os, ArchiveTableEntry& entry)
{
std::size_t filesize = 0;
os >> entry.id;
os >> filesize;
entry.filename.resize(filesize);
os.read(&entry.filename[0], filesize);
os >> entry.filename_crc32 >> entry.real_data_size >> entry.block_data_size >> entry.data_crc32;
os >> entry.data_md5_checksum >> entry.data_offset >> entry.flag;
return os;
}
int main()
{
const char* md5_checksum = "some checksum";
ArchiveTableEntry data;
data.id = 1;
data.filename = "file.txt";
data.filename_crc32 = 10434235;
data.real_data_size = 1024;
data.block_data_size = 256;
data.data_crc32 = 324225252;
data.data_md5_checksum = 1;
std::memset(data.data_md5_checksum, 0, sizeof(data.data_md5_checksum) / sizeof(char));
strcpy(data.data_md5_checksum, md5_checksum);
data.data_offset = 512;
data.flag = 1;
std::fstream out("C:/Users/School/Desktop/Test.bin", std::ios::out);
if (out.is_open())
{
out << data;
out.close();
}
std::fstream in("C:/Users/School/Desktop/Test.bin", std::ios::in);
if (in.is_open())
{
in >> data;
in.close();
}
std::cout<<data.id<<" "<<data.filename<<" "<<data.filename_crc32<<" "<<data.real_data_size<<" "<<data.block_data_size<<" ";
std::cout<<data.data_crc32<<" "<<data.data_md5_checksum<<" ";
}