加载并从文件C 中加载大量的结构化数据

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

本文关键字:加载 结构化 数据 文件      更新时间:2023-10-16

我有一个系统,该系统在结构的向量中存储了许多数据块结构看起来像这样:

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(,我希望将stector的此向量刷成定期,并在启动时从该文件加载。这是当前的文件格式:

"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 Libarys的示例,并具有良好的Documentaion&amp;示例((

( ((

注意: i 知道这里有问题在询问如何执行此操作来自一个包含多个数据块的文件中的大块数据。请在将其标记为重复之前完全阅读我的问题(因为您会明白为什么不是(。

我猜我有很多库可持久(搜索面向对象的数据基本(。如果要将数据写入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;
}