std::fstream 封装加校验

news/2025/1/7 20:07:19/文章来源:https://www.cnblogs.com/narjaja/p/18655700

选自Cartographer_ROS

proto_stream_interface.h

// A writer for writing proto messages to a pbstream.
class ProtoStreamWriterInterface {public:virtual ~ProtoStreamWriterInterface() {}// Serializes, compressed and writes the 'proto' to the file.virtual void WriteProto(const google::protobuf::Message& proto) = 0;// This should be called to check whether writing was successful.virtual bool Close() = 0;
};// A reader of the format produced by ProtoStreamWriter.
class ProtoStreamReaderInterface {public:ProtoStreamReaderInterface() = default;virtual ~ProtoStreamReaderInterface() {}// Deserialize compressed proto from the pb stream.virtual bool ReadProto(google::protobuf::Message* proto) = 0;// 'End-of-file' marker for the pb stream.virtual bool eof() const = 0;
};

proto_stream.h

class ProtoStreamWriter : public ProtoStreamWriterInterface {public:ProtoStreamWriter(const std::string& filename);~ProtoStreamWriter() = default;ProtoStreamWriter(const ProtoStreamWriter&) = delete;ProtoStreamWriter& operator=(const ProtoStreamWriter&) = delete;void WriteProto(const google::protobuf::Message& proto) override;bool Close() override;private:void Write(const std::string& uncompressed_data);std::ofstream out_;
};// A reader of the format produced by ProtoStreamWriter.
class ProtoStreamReader : public ProtoStreamReaderInterface {public:explicit ProtoStreamReader(const std::string& filename);~ProtoStreamReader() = default;ProtoStreamReader(const ProtoStreamReader&) = delete;ProtoStreamReader& operator=(const ProtoStreamReader&) = delete;bool ReadProto(google::protobuf::Message* proto) override;bool eof() const override;private:bool Read(std::string* decompressed_data);std::ifstream in_;
};

proto_stream.h

// First eight bytes to identify our proto stream format.
const uint64 kMagic = 0x7b1d1f7b5bf501db;// 写入8个字节的校验位
void WriteSizeAsLittleEndian(uint64 size, std::ostream* out) {for (int i = 0; i != 8; ++i) {out->put(size & 0xff);size >>= 8;}
}// 读取前8个字节的值, 进行累加
bool ReadSizeAsLittleEndian(std::istream* in, uint64* size) {*size = 0;for (int i = 0; i != 8; ++i) {*size >>= 8;*size += static_cast<uint64>(in->get()) << 56;}return !in->fail();
}}  // namespace// 以二进制方式, 写入的方式打开文件, 并写入8个字节的数据校验
ProtoStreamWriter::ProtoStreamWriter(const std::string& filename): out_(filename, std::ios::out | std::ios::binary) {WriteSizeAsLittleEndian(kMagic, &out_);
}// 将传入的数据先进行压缩, 再写入到文件中
void ProtoStreamWriter::Write(const std::string& uncompressed_data) {std::string compressed_data;// 对数据进行压缩common::FastGzipString(uncompressed_data, &compressed_data);// 根据数据的size写入文件WriteSizeAsLittleEndian(compressed_data.size(), &out_);// 将内存中 compressed_data 以二进制的形式写入文件out_.write(compressed_data.data(), compressed_data.size());
}// 将数据写入文件中
void ProtoStreamWriter::WriteProto(const google::protobuf::Message& proto) {std::string uncompressed_data;proto.SerializeToString(&uncompressed_data);// 压缩并写入Write(uncompressed_data);
}// 关闭打开的文件
bool ProtoStreamWriter::Close() {out_.close();return !out_.fail();
}// 读取pbstream文件, 并对前8个字节的数据进行校验
ProtoStreamReader::ProtoStreamReader(const std::string& filename): in_(filename, std::ios::in | std::ios::binary) {uint64 magic;// 对前8个字节的数据进行校验if (!ReadSizeAsLittleEndian(&in_, &magic) || magic != kMagic) {in_.setstate(std::ios::failbit);}CHECK(in_.good()) << "Failed to open proto stream '" << filename << "'.";
}// 读取数据并解压
bool ProtoStreamReader::Read(std::string* decompressed_data) {uint64 compressed_size;// 获取数据的sizeif (!ReadSizeAsLittleEndian(&in_, &compressed_size)) {return false;}// 根据size生成字符串std::string compressed_data(compressed_size, '\0');// 读取数据放入compressed_data中if (!in_.read(&compressed_data.front(), compressed_size)) {return false;}// 进行解压common::FastGunzipString(compressed_data, decompressed_data);return true;
}// 读取数据并返回protobuf格式的数据
bool ProtoStreamReader::ReadProto(google::protobuf::Message* proto) {std::string decompressed_data;return Read(&decompressed_data) && proto->ParseFromString(decompressed_data);
}bool ProtoStreamReader::eof() const { return in_.eof(); }

调用main

string state_filename;
ProtoStreamReader stream(state_filename);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/865013.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++从入门到精通(第6版)PDF、EPUB免费下载

《C++从入门到精通(第6版)》从初学者角度出发,以通俗易懂的语言和丰富多彩的实例,详细讲解了C++程序开发需要掌握的知识。本书分为4篇共19章:第1篇是基础知识,包括绪论,数据类型,运算符与表达式,条件判断语句,循环语句,函数,数组、指针和引用,以及构造数据类型;第…

C# typeof()实例详解

原文链接:https://www.cnblogs.com/ybqjymy/p/12902845.html 用于获取类型的 System.Type 对象。typeof 表达式采用以下形式:System.Type type = typeof(int); 备注若要获取表达式的运行时类型,可以使用 .NET Framework 方法 GetType,如下所示:1 int i = 0; 2 System.Type…

PhpStorm 2024.3.1.1 安装激活教程(激活至2026,实际上永久,亲测!)以及常见问题处理

申明:本教程 PhpStorm 补丁、激活码均收集于网络,请勿商用,仅供个人学习使用,如有侵权,请联系作者删除。若条件允许,希望大家购买正版 !卸载老版本 PhpStorm 首先,如果小伙伴的电脑上有安装老版本的 PhpStorm , 需要将其彻底卸载掉,如下所示(没有安装则不用管,直…

以太网物理层IOP测试设备TESTBASE-EIOP

OPEN联盟(OPEN Alliance)是一个由OEM、Tier1和Tier2共同组建的非盈利开放性的行业联盟,旨在将以太网技术在汽车环境中应用及推广,TESTBASE-EIOP是经纬恒润自主研发的车载以太网物理层IOP(交互性)自动化测试设备,可完整覆盖OPEN TC8 IOP测试标准。背景OPEN联盟(OPEN All…

Linux命令行连接蓝牙设备

Linux命令行连接蓝牙设备 查看Bluetooth设备: hciconfig启动一个Bluetooth设备,例如:hci0: hciconfig hci0 up相关指令查看特定的Bluetooth设备(例如,设备名为hci0): hciconfig hci0关闭一个Bluetooth设备(例如,设备名为hci0): hciconfig hci0 down修改一个Bluetoot…

华为云专家说:开源的商业化之路与开发者技术服务

开源在大量在云技术以及业务中应用,从开源与云的增长模式看,开源与云具有相当程度的相似性。本文来源:《华为云DTSE》第五期开源专刊,作者:华为云开发者支持首席布道师汪盛 开源、云的增长模式与 Product Led Growth具有较大相似性,两者增长立足于产品质量与使用的开发者…

JAVA-Day 06:if语句的三种形式

if语句的三种形式if(表达式){语句体}如果小括号里的表达式结果为真,则执行大括号中的语句体,如下图例子所示:2.if(表达式){语句体}else{语句体} 如果小括号里的表达式为真,则执行else前的大括号中的语句体,如果小括号里的表达式为假,则执行else后的大括号中的语句体。如下图…

Redis可视化工具 Another Redis Desktop Manager工具使用详细教程(附下载链接)

Redis 可视化工具推荐:Another Redis Desktop Manager Redis 是一种高性能的键值数据库,广泛应用于缓存和消息队列等场景。对于开发者来说,命令行工具固然强大,但操作繁琐。而一款高效易用的可视化工具可以极大地提升使用效率。本篇将为大家推荐一款开源、跨平台且功能强大…

跟狂神学习第一天,了解Markdown语法

Markdown学习 一个#+空格+标题名字=大标题/一级标题 二级标题 两个#+空格+标题 = 二级标题 三个#+空格+标题 = 三级标题 .......(以此类推) 一直到六级标题 字体 hello! 粗体:文字两边同时加两个* hello! 斜体:文字两边同时加一个* hello! 斜体加粗:文字两边同时加三个…

Ubuntu换源自用备用

Ubuntu换源(本地) 作者 原文链接:https://blog.csdn.net/MacWx/article/details/137689898 查询系统版本 lsb_release -a系统版本是 Ubuntu 20.04.6 LTS,注意这个开发代号Codename,Ubuntu每一个版本都有一个代号,这个一定要跟国内源对应,否则会出问题。 阿里云Ubuntu镜像…

大规模高性能云网络技术思路

控制面基础架构采用微服务架构模型,服务独立可扩展,可以根据每个服务的规模来部署满足需求的实例。具体网络控制面技术方案如图本文分享自天翼云开发者社区《大规模高性能云网络技术思路》,作者:程****超 控制面基础架构采用微服务架构模型,服务独立可扩展,可以根据每个服…

Python开发环境部署教程

本教程将详细介绍如何在 Windows 系统上配置 Python 开发环境,包括安装 Python、配置虚拟环境以及使用 VS Code 进行开发,适合新手和需要精细配置的开发者。本教程将详细介绍如何在 Windows 系统上配置 Python 开发环境,包括安装 Python、配置虚拟环境以及使用 VS Code 进行…