【问题标题】:Reading binary file with batch size using boost serialization使用boost序列化读取具有批量大小的二进制文件
【发布时间】:2018-06-29 10:38:11
【问题描述】:

我正在尝试使用 boost 的二进制序列化器对类进行序列化,并以批量大小加载二进制数据。

我能够从 10 条记录中提取前 5 条记录,当我尝试通过重新打开文件并将文件读取指针重新设置为前一条记录来读取另外 5 条记录时,进程崩溃了。我很确定,我在这里遗漏了一些东西来正确地重新设置文件读取指针。

#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/string.hpp>
#include <fstream>
#include <iostream>

using namespace std;
using namespace boost::archive;
class logEntry {
 private:
    size_t m_txID;
    string m_jsonStr;

    friend class boost::serialization::access;
    template <typename Archive>
    friend void serialize( Archive &ar, logEntry &l, const unsigned int version );

 public:
    logEntry() {
        m_txID = 0;
        m_jsonStr = "";
    }
    logEntry( size_t id, const string &val ) {
        m_txID = id;
        m_jsonStr = val;
    }
    string getJsonValue() {
        return m_jsonStr;
    }

    size_t getTxId() {
        return m_txID;
    }
};

template <typename Archive>
void serialize( Archive &ar, logEntry &l, const unsigned int version ) {
    ar &l.m_txID;
    ar &l.m_jsonStr;
}

size_t prevReadPos = 0;

void save() {
    ofstream        file{"/tmp/test.bin", ios::binary | ios::trunc};
    binary_oarchive oa{file};

    // Save 10 records
    for ( int i = 0; i < 10; i++ )
        oa << logEntry( i, "{Some Json String}" );

    file.flush();
    file.close();
}

// Load data batch wise
void load( size_t bsize ) {
    ifstream        file{"/tmp/test.bin", ios::binary};
    binary_iarchive ia{file};

    // Record file length
    size_t fileEnd;
    size_t beg = file.tellg();

    file.seekg( 0, ios::end );
    fileEnd = file.tellg();

    // Reset the file pointer to the beginning of the file OR to the previous read position
    if ( prevReadPos == 0 )
        file.seekg( beg, ios::beg );
    else
        **  // THIS IS THE PLACE I AM RESTORING THE PREVIOUS READ POSITION, WHICH IS CAUSING THE PROCESS
            // TO CRASH.**
         file.seekg( prevReadPos, ios::beg );

    // Load records batch wise until we reach the end of the file
    logEntry l;

    for ( size_t i = 0; i < bsize && file.tellg() < fileEnd; i++ ) {
        ia >> l;
    }
    prevReadPos = file.tellg();
    file.close();
}

int main() {
    save();
    while ( 1 ) {
        load( 5 );
        sleep( 5 );
    }
}

【问题讨论】:

    标签: c++ boost binary binaryfiles serialization


    【解决方案1】:

    您使用错误的 Boost 序列化。

    档案不是“随机访问”。它们是带有标题和(可能)结束序列的完整存储格式。

    如果您创建一个包含 10 条记录的档案,您将 [必须] 阅读整个档案。当然,您可以中途停下来,因为,您知道,您还不需要阅读其余部分。但当然你不能指望以后再读其余的,就好像一个全新的档案是从那时开始的,因为没有。结果是Undefined Behaviour

    另请参阅有关将多个档案合并到一个文件中的信息(除非使用您自己的描述格式,否则您不想这样做):

    【讨论】:

      猜你喜欢
      • 2014-09-20
      • 1970-01-01
      • 2016-12-17
      • 1970-01-01
      • 2015-04-03
      • 2015-09-05
      • 2011-03-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多