使用提升序列化读取具有批大小的二进制文件

Reading binary file with batch size using boost serialization

本文关键字:二进制文件 升序 序列化 读取      更新时间:2023-10-16

我正在尝试使用 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 );
    }
}
您使用了

错误的提升序列化。

档案不是"随机访问"。它们是完整的存储格式,带有标头和(可能(关闭序列。

如果您创建一个包含 10 条记录的存档,您将 [必须] 读取整个存档。当然,你可以中途停下来,因为,你知道,你还不需要阅读其余的。但是,当然,您不能指望稍后再阅读其余内容,就好像那时开始了一个全新的存档一样,因为没有。结果是未定义的行为。

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

  • 存档不是流
  • 输出比多态文本存档更多的东西