讲师中心 微信公众号
AI工具推荐 视频效率加速

c++怎么利用文件流实现简单的数据库管理系统(DBMS)底层读写【进阶】

阿静小哥_8442

阿静小哥_8442

发布时间:2026-03-24 18:55:33

|

641人浏览过

|

来源于php中文网

原创

因结构体含非POD成员(如std::string)、内存填充或未用binary模式,导致write()写入无效地址或字节错位。须用POD结构、#pragma pack(1)、固定数组、memset清零,并显式指定binary模式。

c++怎么利用文件流实现简单的数据库管理系统(dbms)底层读写【进阶】

用 std::fstream 直接读写结构体数据,为什么常读出乱码或崩溃

因为 C++ 结构体默认是「非 POD 类型」或含对齐填充,直接 write() 内存块时,sizeof(MyStruct) ≠ 实际有效字段字节数,且不同编译器/平台的内存布局可能不一致。更关键的是:一旦结构体里有 std::string、std::vector 这类动态成员,它们只存指针,write() 出去的就是野地址。

  • 必须用 POD(Plain Old Data)结构体:只含基本类型、数组、其他 POD 成员,无构造函数、虚函数、非 public 成员
  • 显式加 #pragma pack(1) 或 alignas(1) 消除填充字节(尤其跨平台时)
  • 禁止出现 std::string;改用固定长度字符数组,如 char name[32]
  • 写入前用 memset(&obj, 0, sizeof(obj)) 清零,避免未初始化内存参与序列化

示例合法结构体:

struct Record {
    int id;
    char name[32];
    double score;
} __attribute__((packed)); // GCC 方式,MSVC 用 #pragma pack(1)

如何安全地追加记录并支持随机读取第 N 条

文件不是数据库引擎,没有索引,靠偏移计算定位是最直接方式 —— 但前提是每条记录长度严格固定。

  • 先用 seekg(0, std::ios::end) 获取文件总大小,再除以 sizeof(Record) 得到当前记录数
  • 读第 n 条:用 seekg(n * sizeof(Record)) 跳转,再 read() 一个 Record 实例
  • 写新记录:seekp(0, std::ios::end) 后直接 write(),不要用 append 模式(它在某些标准库实现中行为不一致)
  • 务必检查 write() 返回值是否等于 sizeof(Record),否则说明磁盘满或权限失败

错误示范:fstream.open("db.bin", ios::in | ios::out | ios::app) —— app 会强制所有写入都在末尾,且 seekp() 失效。

立即学习“C++免费学习笔记(深入)”;

C++ 算法竞赛自动化测试数据生成与校验框架
C++ 算法竞赛自动化测试数据生成与校验框架

根据原题生成新题面、验证器及完整测试数据,自动套用 testlib 模板,用于用户要求生成测试数据时。

下载

删除某条记录时,为什么不能直接把后面的数据往前搬

可以搬,但代价高:每次删都要重写后面全部数据,O(N) 时间 + 频繁磁盘 IO。更实际的做法是「逻辑删除」+ 空间复用。

  • 在结构体开头加一个 bool valid 字段(或用特殊值如 id == -1 标记已删)
  • 插入新记录时,先 scan 文件找第一个 valid == false 的空位,优先复用
  • 如果找不到空位,再追加到末尾
  • 定期提供 vacuum() 手动整理:读出所有 valid == true 的记录,写入新文件,替换原文件(注意原子性:写完 rename() 替换)

注意:valid 字段本身也要参与 pack 对齐,否则结构体大小会因 padding 变化。

遇到 ios_base::failure 或读出全零数据,该查什么

这不是“文件打不开”那么简单,而是流状态机进入失败态后,后续所有操作都静默失败。

  • 每次 read()/write() 后立即检查 if (!fs.good()) 或 if (fs.fail()),而不是等最后统一判断
  • 常见诱因:seekg() 超出文件末尾(返回 pos_type(-1)),或 read() 请求长度超过剩余字节
  • Windows 下路径含中文或空格易触发编码问题,优先用 UTF-8 编码路径(C++20 std::filesystem::u8path)或转义为短路径
  • 调试时用 fs.tellg() 打印当前位置,确认跳转是否成功;用 fs.rdstate() 查具体哪位标志置位

最易被忽略的一点:二进制模式必须显式指定 —— std::ios::binary 缺失会导致 Windows 下 \n 被误转成 \r\n,破坏结构体对齐。

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

Lovart
Lovart Hot

一款面向视觉设计创作的AI设计平台,可通过智能体和画布工作流辅助制作海报、Logo、网页、PPT及其他视觉内容。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

5239

2023.08.02

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

3974

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

4131

2025.07.04

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

3974

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

4131

2025.07.04

C++ 智能指针与现代内存管理
C++ 智能指针与现代内存管理

深入讲解 C++ 现代内存管理的核心工具——智能指针,涵盖 unique_ptr 独占所有权语义、shared_ptr 引用计数机制与循环引用问题、weak_ptr 弱引用的应用场景、make_unique/make_shared 工厂函数的性能优势、自定义删除器的编写、RAII 资源管理思想的实践,以及从裸指针迁移到智能指针的重构策略,帮助开发者编写安全无泄漏的现代 C++ 代码。

299

2026.04.23

append用法
append用法

append是一个常用的命令行工具,用于将一个文件的内容追加到另一个文件的末尾。想了解更多append用法相关内容,可以阅读本专题下面的文章。

578

2023.10.25

python中append的用法
python中append的用法

在Python中,append()是列表对象的一个方法,用于向列表末尾添加一个元素。想了解更多append的更多内容,可以阅读本专题下面的文章。

1476

2023.11.14

Buffalo框架数据库开发全教程
Buffalo框架数据库开发全教程

本专题围绕Buffalo框架数据库开发,讲解database.yml多环境配置、soda与fizz迁移生成回滚、模型结构体标签、增删改查与条件查询、一对多与多对多关联、数据校验、回调钩子、事务处理及原生SQL执行能力。

60

2026.09.23

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Conan 2 Essentials 免费课程
Conan 2 Essentials 免费课程

共0课时 | 0人学习

CMake 与 Conan 集成实践
CMake 与 Conan 集成实践

共0课时 | 0人学习

Conan 2 高级依赖模型介绍
Conan 2 高级依赖模型介绍

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn