首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在文件c++中加载和保存大量结构化数据

在文件c++中加载和保存大量结构化数据
EN

Stack Overflow用户
提问于 2019-08-04 17:40:11
回答 1查看 254关注 0票数 3

我有一个系统,它将大量数据块存储在一个结构向量中,结构如下所示:

代码语言:javascript
复制
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),希望定期将这个结构向量刷新到其中,并在启动时从该文件加载。这是当前的文件格式:

代码语言:javascript
复制
"BLK"
index (height)
blockhash
previous block hash
"TXNS"
tx indexes
"ENDTXNS"
timestamp
extra data
"ENDBLK"

我试图创建一个函数,将其加载到结构中,但它非常复杂,效率很低。这是我将要使用的代码的开始。

代码语言:javascript
复制
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;
                    }
                }

你知道我想从密码里做什么。萨利,有一种花言巧语可以使这更有效吗?或者我只是错误地证明了这一点(例如我是否应该以json格式保存它(如果是这样的话,请提供一些易于使用和理解的c++ libarys示例,并具有良好的文档和示例))

注意:i知道这里有一些问题询问如何做到这一点,但是没有人试图从一个包含多个数据块的文件中读取这么大的数据块。请仔细阅读我的问题,然后再把它标记为副本(因为你会明白为什么它不是)。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-08-05 12:39:36

我想有许多用于对象持久性的库(搜索面向对象的数据库)。如果要将数据写入bin文件,只需编写saveload函数即可。就像这样:

代码语言:javascript
复制
#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;
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57348861

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档