从文件中加载和保存大量结构化数据 C++

Load and save a large amount of structured data to and from a file c++

我的系统有很多数据块存储在结构向量中 该结构如下所示:

class Block {
public: 
    Blockheader header;
    uint32_t index;
    std::string hash; 
    std::string prevhash;
    std::vector<tx_data> transactions; 
    uint64_t timestamp; 
    std::string data; 
};

我有一个文件 (blocks.bin),我希望定期将结构的这个向量刷新到该文件中,并在启动时从该文件加载。 这是当前的文件格式:

"BLK"
index (height)
blockhash
previous block hash
"TXNS"
tx indexes
"ENDTXNS"
timestamp
extra data
"ENDBLK"

我试图制作一个将其加载到结构中的函数,但它非常复杂且效率低下。这是我要使用的代码的开头。

std::ifstream blockFile(path +"/blocks.bin");
uint16_t readState;
            uint16_t readIndex; 
            Block Blocks;
            for( std::string fileTemp; getline( blockFile, fileTemp ); )
            {
                if (fileTemp == "BLK") {
                    readState = 0;
                    goto Escape;
                }
                if (fileTemp == "TXNS") {
                    readState = 1;
                    goto Escape;
                }
                if (fileTemp == "ENDTXNS") {
                    readState = 2;
                    goto Escape;
                }
                if (fileTemp == "ENDBLK") {
                    readState = 3;
                    goto Escape;
                }
                if (readState = 0) {
                    if (readIndex = 0) {
                        Blocks.height = fileTemp;
                    }else if (readIndex = 1) {
                        Blocks.hash = fileTemp;
                    }else if (readIndex = 2) {
                        Blocks.previousHash = fileTemp;
                    }
                    readIndex++
                                        if (readIndex > 2) {
                        readIndex = 0;
                    }
                }

你知道我试图从该代码做什么。 Surley 那里有一个图书馆可以提高效率吗?还是我只是以错误的方式解决这个问题(例如,我应该将其保存为 json 格式(如果是这样,请提供一些易于使用和理解并具有良好文档和示例的 C++ 库示例))

注意:知道这里有问题在问怎么办然而,他们中的 none 正试图从一个包含多个数据块的文件中读取如此大的数据块。请在将其标记为重复之前通读我的问题(因为您会明白为什么不是)。

我想有很多用于对象持久化的库(搜索 Object-Oriented-Data-Base)。如果要将数据写入 bin 文件,只需编写 saveload 函数即可。像这样:

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

struct Blockheader
{
    void save(std::fstream&) const {}
    void load(std::fstream&) {}

};

struct tx_data
{
    void save(std::fstream&) const {}
    void load(std::fstream&) {}
};

class Block
{
public: 
    void save(std::fstream& output) const
    {
        size_t size;

        // blockheader
        header.save(output);

        // index
        output.write((char*)&index,sizeof(index));

        // hash
        size = hash.size();
        output.write((char*)&size,sizeof(size));
        output.write(hash.c_str(),size);

        // prevhash
        size = prevhash.size();
        output.write((char*)&size,sizeof(size));
        output.write(prevhash.c_str(),size);

        // transactions
        size = transactions.size();
        output.write((char*)&size,sizeof(size));
        for (const auto& transaction : transactions)
            transaction.save(output); // write the save function for tx_data

        // timestamp
        output.write((char*)&timestamp,sizeof(timestamp));

        // data
        size = data.size();
        output.write((char*)&size,sizeof(size));
        output.write(data.c_str(),size);
    }

    void load(std::fstream& input)
    {
        size_t size;

        // header
        header.load(input);

        // index
        input.read((char*)&index,sizeof(index));

        // hash
        input.read((char*)&size,sizeof(size));
        hash.resize(size);
        input.read(&hash[0],size);

        // prevhash
        input.read((char*)&size,sizeof(size));
        prevhash.resize(size);
        input.read(&prevhash[0],size);

        // transactions
        input.read((char*)&size,sizeof(size));
        transactions.clear();
        transactions.reserve(size);
        for (unsigned i=0; i<size; ++i)
        {
            tx_data transaction;
            transaction.load(input);
            transactions.emplace_back(std::move(transaction));
        }

        // timestamp
        input.read((char*)&timestamp,sizeof(timestamp));

        // data
        input.read((char*)&size,sizeof(size));
        data.resize(size);
        input.read(&data[0],size);
    }

    Blockheader header;
    uint32_t index;
    std::string hash = "hash"; 
    std::string prevhash = "prevhash";
    std::vector<tx_data> transactions; 
    uint64_t timestamp; 
    std::string data; 
};

int main()
{
    // write blocks to file
    std::vector<Block> blocks(10);
    {
        std::fstream output("data.bin",std::ios::out|std::ios::binary);
        if (output.is_open())
        {
            size_t size = blocks.size();
            output.write((char*)&size,sizeof(size));
            for (const auto& block : blocks)
                block.save(output);
        }
    }

    // load blocks from file
    blocks.clear();
    {
        std::fstream input("data.bin",std::ios::in|std::ios::binary);
        if (input.is_open())
        {
            size_t size;
            input.read((char*)&size,sizeof(size));
            blocks.reserve(size);
            for (unsigned i=0; i<size; ++i)
            {
                Block block;
                block.load(input);
                blocks.emplace_back(std::move(block));
            }
        }
    }

    return 0;
}