【C++ 存储和读取二进制文件以及类的实例】

2023-11-14

很多时候程序运行时的数据都以类的对象的形式存储,那么如何将这些对象保存使得下一次运行程序的时候可以直接使用呢?

Step 1> 首先我们需要知道如何读写二进制文件:

inline size_t readBinaryFile(const char * filename,unsigned char* & data) 
{
    FILE* fp;
    fopen_s(&fp,filename, "rb");
    if (fp == NULL) return 0;  //空指针则返回0,文件打开失败
    fseek(fp, 0, SEEK_END);  //将文件指针移动至文件末尾
    size_t size = ftell(fp);  //计算文件大小,单位:Byte
    fseek(fp, 0, SEEK_SET); //把文件指针移回初始位置(文件开头)
    data = (unsigned char *)malloc(sizeof(unsigned char)*size);
    fread(data,size,1,fp);
    fclose(fp);
    return size;
}


//size:要写入的数据大小(单位:字节)
inline size_t writeBinaryFile(const char* filename, const unsigned char* data, size_t size)  
{
    FILE* fp;
    fopen_s(&fp,filename, "wb");
    if (fp == NULL) return 0;
    size_t written_size= fwrite(data, size, 1 ,fp);
    fclose(fp);
    return written_size;
}

注意这里readBinaryFile函数参数中的data指针必须得用引用,或者使用指针的指针,这是因为在函数内对指针重新分配了内存,如果只传指针,那么经过值传递之后形参实际上是实参的拷贝,对形参重新分配内存并不会改变实参(且指向的地址不再是实参的值了),写入的数据在函数外也无法访问。

Step 2 > 我们通过函数模板,将传入的任意类对象转成字节数组写入或者读取二进制文件即可

template<typename OB>
inline void saveObject(const char*filename,OB & object) //传入要保存的对象引用
{
    std::ofstream osm(filename, ios::out | ios::binary);
    osm.write((const char *)&object,sizeof(OB));
    osm.close();
}

template<typename OB>
inline void readObject(const char* filename, OB * object) //传入读取之后对象存储的指针
{
    std::ifstream ism(filename, ios::in | ios::binary);
    ism.read((char*)object, sizeof(OB));
    ism.close();
}

这里我们没有重新分配对象指针,因此可以不用写引用

以上使用到的头文件:
<stdio.h> - fopen_s函数和FILE类型
< fstream > - ifstream , ofstream
<stdlib.h> - malloc函数

References

  1. https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/fopen-s-wfopen-s?view=msvc-160
  2. http://www.cplusplus.com/reference/cstdlib/malloc/?kw=malloc
  3. http://www.cplusplus.com/reference/istream/istream/
  4. http://www.cplusplus.com/reference/fstream/ofstream/
  5. https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/fseek-fseeki64?view=msvc-160
  6. https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/ftell-ftelli64?view=msvc-160


原文链接:https://blog.csdn.net/qq_42885747/article/details/111845680

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【C++ 存储和读取二进制文件以及类的实例】 的相关文章

随机推荐

  • torch.transpose()函数

    torch transpose Tensor dim0 dim1 是pytorch中的ndarray矩阵进行转置的操作 注意 transpose 一次只能在两个维度间进行转置 也可以理解为维度转换 例如 import torch as t
  • 命令行启动anaconda

    命令行启动anaconda anaconda navigator
  • VsCode使用技巧:避免ubuntu版本右键菜单误点

    问题描述 ubuntu版本 16 04 的VsCode 1 69版本 经常在代码界面下单击右键总会点到右键菜单中的某一项上面 只有每次点下的时候把鼠标向左移动再弹起才能避免 比如我们调试时 想把某个变量添加到监视 但是单击右键菜单 老是直接
  • gitlab常用的命令

    引言 使用gitlab提交代码的时候 若是使用的命令行 则需要输入命令行指令 下面是日常遇到的常用的命令行指令 详情 git命令行常用指令的使用 git status 上次提交后是否对文件再做了修改项目1 git add 添加所有的变动 g
  • python中的pass是什么意思_Python中pass的作用与使用教程

    Python中pass的作用与使用教程 Python中pass的作用 空语句 do nothing 保证格式完整 保证语义完整 以if语句为例 在c或c java中 if true do nothing else do something
  • SQLite与MySQL、SQLServer等异构数据库之间数据同步的解决方案

    什么是SQLite DBSync SQLite DBSync是开源嵌入式数据库SQLite的数据同步引擎 实现了SQLite与SQLite数据库之间以及SQLite与异构数据库 Oracle MySQL SQLServer 之间的增量的 双
  • 用Gecco爬虫采集数据

    说起网络爬虫大家首先都会想到python爬虫 但是用Java实现爬虫的也很多 也有很多爬虫框架 今天我想说说我使用什么做爬虫的 其实我也是一个爬虫白痴 刚接触爬虫的时候都是用纯java去做 但是做到一半的时候发现要写的代码真多 所以就找Ja
  • Linux上的虚拟化技术

    虚拟化技术的方法 架构和实现概览 2006年12月29日 虚拟化技术的应用十分广泛 当前虚拟化技术主要关注于服务器的虚拟化 或在单个主机上寄存多个独立的操作系统 本文首先介绍虚拟化技术的原理 然后讨论多个虚拟化技术的实现方法 另外介绍了一些
  • 铱(Iridium)系统的通信体制

    铱系统已经是很老的系统了 但对于我们深刻了解低轨卫星通信系统还是很有帮助的 窥一斑而知全豹 铱系统是世界上第一个LEO全球卫星移动通信系统 1995年1月获得美国联邦通信委员会看许可 1997年5月发射第一颗卫星 1998年5月完成星座布置
  • 【React+TS】从零开始搭建react+typescript+router+redux+less+pxToVw自适应+sass+axios反向代理+别名@+Antd-mobile

    一 通过create react app脚手架创建项目 npx create react app testproject template typescript 在vscode中打开项目 可以看到顺利生成了react项目且组件的后缀为tsx
  • 关于parallelStream()引发线程不安全问题

    一 问题代码 public class ParallelStreamTest public static void main String args List
  • 即兴讲话的万能公式(赶过猪)

    即兴讲话就是在没有充分准备的情况下进行的讲话 很多人在即兴演讲的时候会心跳加速 语无伦次 大脑一片空白 甚至手脚发麻 有时候即使经过准备 演讲稿已经写好了 上台前也背诵过了 但是一到台上还是紧张的 稿子都忘记了 其实造成这种情况 很大部分的
  • ping, ping6 (icmp, icmpv6)

    选项 I interface address Set source address to specified interface address Argument may be numeric IP address or name of d
  • Django 从零开始实现简单的restful应用

    安装Django 我是在windows上安装的 之后在linux上试一下再补充上来 可以通过pip直接安装 pip install django 需要使用到mysql 数据库 pip install mysqlclient 新建项目 安装以
  • Node =》 nodemon

    在编写调试Node js的时候 如果修改了项目的代码 则需要频繁的手动close掉 然后再重新启动 非常频繁 现在可通过nodemon这个工具 能够监听项目文件的变动 当代码被修改后 nodemon会帮我们重新启动项目 极大方便了开发和调试
  • 在CSDN学Golang云原生(git)

    一 git的工作流程 Golang的Git工作流程与其他语言的Git工作流程类似 通常包括以下步骤 创建分支 在本地代码库中创建一个新的分支 该分支用于开发新功能或修复错误 编写代码 在创建的分支上进行编码 并将更改提交到本地版本控制库中
  • 【Egg从基础到进阶】一:Egg项目初始化及基础入门

    目录 Egg js 为企业级框架和应用而生 我们希望由 Egg js 孕育出更多上层框架 帮助开发团队和开发人员降低开发和维护成本 使用Egg 脚手架创建一个Egg项目 node gt 14 20 0 app router app cont
  • Java架构师技术进阶路线图详解

    在企业里 一名架构师已经可以算是高端人物了 但架构师也是需要学习的 任何人与事物都需要学习 下面我们就来了解一下Java架构师到底该如何进阶 请看如下 一 阅读源码 深入的Java学习 经典源码阅读不可少 常见的设计模式 编码必备 Spri
  • 如何给elementui中表格的行设置样式

  • 【C++ 存储和读取二进制文件以及类的实例】

    很多时候程序运行时的数据都以类的对象的形式存储 那么如何将这些对象保存使得下一次运行程序的时候可以直接使用呢 Step 1 gt 首先我们需要知道如何读写二进制文件 inline size t readBinaryFile const ch