# 文件内存管理系统全家桶 **Repository Path**: xr_jesse/BFMMS_FB ## Basic Information - **Project Name**: 文件内存管理系统全家桶 - **Description**: 把内存和文件统一成同一套操作语义的C++20模块化基座。MES强制错误消费,BMMS零外部碎片内存池,BFS显式缓存文件视图。数据从磁盘到寄存器,全程同一套代码范式。是新语言运行时DF_ES的基座,也可以在一般的CPP20项目上使用,注意:只支持64位系统。想看README.md的化进来之后多往下翻点,就像五金店的老板总在最里面 - **Primary Language**: C++ - **License**: MIT - **Default Branch**: master - **Homepage**: https://gitee.com/xr_jesse - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 0 - **Created**: 2026-02-12 - **Last Updated**: 2026-03-15 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 📦 文件内存管理系统全家桶 ## 📋 功能简介 这是一个**统一内存与文件操作语义**的C++20模块化系统,提供从内存池化分配到文件缓存管理的完整解决方案。 ### 核心功能 - **统一操作接口**:内存操作和文件操作使用完全相同的函数签名 - **零碎片内存池**:静态卷(固定大小)和动态卷(可变大小)两种分配策略 - **文件缓存代理**:将文件区域映射为内存视图,实现零拷贝访问 - **强制错误消费**:未检查的错误/警告阻止结果获取 - **区域视图**:物理资源的逻辑子视图,支持内存和文件的局部映射 --- ## ✨ 优点介绍 ### 1. 统一语义,降低心智负担 ```cpp // 内存操作 agent_ptr.load(0, 1024, another_ptr, 0, true); // 文件操作(语法完全一致) file_agent_ptr.load(0, 1024, another_fap, 0, true, mes); ``` **学会一个,全会。** ### 2. 零外部碎片的内存池 - **static_volume**:固定块大小,释放即复用,碎片无法产生 - **free_volume**:动态分配,支持物理内存归还系统 - **static_volume_part**:多个逻辑分区共享同一物理内存池 ### 3. 文件缓存零拷贝 文件缓存直接由内存池管理,业务层可直接借用: ```cpp // 文件缓存就是agent_ptr bmms_f::agent_ptr& cache = file_agent_ptr.get_cache_agent_ptr(); // 直接操作内存,无需二次复制 ``` ### 4. 显式控制,无黑盒行为 - 显式标记脏页:`__mark_dirty__()` - 显式刷盘:`push_cache_to_bin_file()` - 显式拉取:`pull_cache_from_bin_file()` ### 5. 强制错误消费,保障业务安全 ```cpp res.set_err(error, true); // 标记为"必须检查" // ... 忘记检查 ... auto result = res.move_result(); // 触发编码错误,进程终止 ``` ### 6. 区域即视图,物理逻辑分离 - **static_volume_part**:内存区域的逻辑子视图 - **file_agent_ptr**:文件区域的逻辑子视图 - 同一物理资源可划分多个独立逻辑区域 --- ## 🚀 快速开始 ### 环境要求 - C++20 Modules支持(MSVC 2022 17.5+ / Clang 17+ / GCC 14+) - 标准库头文件:``, ``, ``等 # 📦 文件内存管理系统全家桶 —— 使用案例集 ## 案例一:类型安全的数据持久化(最简模式) ```cpp import MES; import BMMS; import BFS; mes::a_mes mes; // ===== 1. 打开文件 ===== auto file = std::make_shared( "config.bin", 1024, bfs_f::bin_file::init_type::open_existed, mes ); // ===== 2. 定义类型数据 ===== struct Config { int version = 1; double scale = 1.5; char name[32] = "default"; void upgrade() { version++; } }; Config cfg; // ===== 3. 创建代理指针包装类型数据 ===== bmms_f::agent_ptr cfg_agent(&cfg, sizeof(Config)); // ===== 4. 从文件加载到类型数据 ===== file->load_to_agent_ptr(0, sizeof(Config), cfg_agent, 0, true, mes); // ===== 5. 业务逻辑:直接操作类型 ===== cfg.upgrade(); cfg.scale = 2.0; // ===== 6. 保存回文件 ===== file->store_from_agent_ptr(cfg_agent, 0, sizeof(Config), 0, true, true, mes); ``` **语义**:`Config` 对象直接作为数据载体,代理指针只是"视图",业务代码操作的是类型本身。 --- ## 案例二:内存池 + 文件缓存(零拷贝) ```cpp import MES; import BMMS; import BFS; mes::a_mes mes; // ===== 1. 创建内存池 ===== auto vol = std::make_shared( 4096, 100, // 4KB块,100个 bmms_f::static_volume::init_type::no_init_all_size, bmms_f::static_volume::alignment_type::byte_8, mes ); // ===== 2. 从池中分配一块 ===== bmms_f::static_volume_ptr block(vol, mes); // ===== 3. 打开文件 ===== auto file = std::make_shared( "data.bin", 1024 * 1024, bfs_f::bin_file::init_type::open_existed, mes ); // ===== 4. 将内存块绑定为文件缓存区域 ===== bfs_f::file_agent_ptr cache( file, // 文件 8192, // 从文件偏移8192开始 4096, // 缓存大小4KB block.get_agent_ptr(), // 使用池中分配的内存 mes ); // ===== 5. 定义业务数据结构 ===== struct Packet { uint64_t id; uint32_t type; uint8_t data[4064]; // 剩余空间 }; Packet pkt; // ===== 6. 从文件加载到业务对象 ===== bmms_f::agent_ptr pkt_agent(&pkt, sizeof(Packet)); cache.load_to_agent_ptr(0, sizeof(Packet), pkt_agent, 0, true, mes); // ===== 7. 业务处理 ===== pkt.id++; pkt.type = 2; // ===== 8. 写回缓存(自动标记脏页)===== cache.store_from_agent_ptr(pkt_agent, 0, sizeof(Packet), 0, true, mes); // ===== 9. 刷回磁盘 ===== cache.push_cache_to_bin_file(mes); ``` **语义**:内存池、文件缓存、业务对象三者分离,通过代理指针建立关联,数据流动清晰。 --- ## 案例三:`static_volume_part` 轻量化逻辑分区 ```cpp import MES; import BMMS; mes::a_mes mes; // ===== 1. 创建物理内存池 ===== auto phys_vol = std::make_shared( 64, 1000, // 64字节块,1000个 bmms_f::static_volume::init_type::init_all_size, bmms_f::static_volume::alignment_type::byte_8, mes ); // ===== 2. 创建三个逻辑分区,共享同一物理池 ===== bmms_f::static_volume_part session_pool( phys_vol, 200, // 200个块的会话池 bmms_f::static_volume_part::init_type::no_init_all_size, bmms_f::static_volume_part::control_type::not_allow_over_use, mes ); bmms_f::static_volume_part cache_pool( phys_vol, 500, // 500个块的缓存池 bmms_f::static_volume_part::init_type::no_init_all_size, bmms_f::static_volume_part::control_type::not_allow_over_use, mes ); bmms_f::static_volume_part temp_pool( phys_vol, 300, // 300个块的临时池 bmms_f::static_volume_part::init_type::no_init_all_size, bmms_f::static_volume_part::control_type::allow_over_use, // 允许超用! mes ); // ===== 3. 定义业务数据 ===== struct UserSession { uint64_t uid; char name[32]; time_t login_time; }; UserSession session; // ===== 4. 在会话池中分配空间 ===== bmms_f::agent_ptr session_agent(&session, sizeof(UserSession)); session_pool.store_from_void_ptr(&session, sizeof(UserSession), 0, true, mes); // ===== 5. 使用完毕后释放块(产生空洞)===== session_pool.free_block(0); // 块索引0被释放 // ===== 6. 临时池超用示例 ===== struct BigData { char data[1024]; }; BigData big; // 临时池允许超用,虽然物理池只剩100个块(因为session+缓存用了700), // 但逻辑上可以分配200个块,只有真正写入时才检查物理空间 for(int i = 0; i < 150; i++) { temp_pool.store_from_void_ptr(&big, sizeof(BigData), i * 1024, true, mes); // 前100次成功,第101次开始会触发服务错误 } ``` **语义**:物理内存共享,逻辑视图隔离。`allow_over_use` 让逻辑空间可以大于物理空间,适合临时缓冲区。 --- ## 案例四:空洞利用与动态调整 ```cpp import MES; import BMMS; mes::a_mes mes; auto vol = std::make_shared( 1024, 100, bmms_f::static_volume::init_type::init_all_size, bmms_f::static_volume::alignment_type::byte_8, mes ); bmms_f::static_volume_part part( vol, 50, bmms_f::static_volume_part::init_type::no_init_all_size, bmms_f::static_volume_part::control_type::not_allow_over_use, mes ); // ===== 1. 分配一些块 ===== struct Record { int id; double value; }; Record rec; for(int i = 0; i < 30; i++) { part.store_from_void_ptr(&rec, sizeof(Record), i * sizeof(Record), true, mes); } // ===== 2. 释放中间的一块(产生空洞)===== part.free_block(15); // 块15被释放 // ===== 3. 空洞会被自动重用 ===== Record new_rec; part.store_from_void_ptr(&new_rec, sizeof(Record), 15 * sizeof(Record), true, mes); // 自动从物理池重新分配块15 // ===== 4. 调整分区大小(缩小)===== part.resize(40, mes); // 后10个块被释放回物理池 // ===== 5. 调整分区大小(扩大)===== part.resize(60, mes); // 新增加的20个块初始为未分配状态 ``` **语义**:空洞的产生和填充对上层透明,`resize` 动态调整逻辑空间大小。 --- ## 案例五:文件 + 内存池 + 业务对象完整流水线 ```cpp import MES; import BMMS; import BFS; import ; mes::a_mes mes; // ===== 1. 基础设施 ===== auto file = std::make_shared( "database.bin", 10 * 1024 * 1024, bfs_f::bin_file::init_type::open_existed, mes ); auto pool = std::make_shared( 512, 1000, bmms_f::static_volume::init_type::no_init_all_size, bmms_f::static_volume::alignment_type::byte_8, mes ); // ===== 2. 业务数据定义 ===== struct Entry { uint64_t key; uint32_t flags; uint8_t data[500]; void update() { flags |= 0x01; } }; // ===== 3. 处理一批数据 ===== std::vector entries(10); for(size_t i = 0; i < entries.size(); i++) { // 3.1 从池中分配块 bmms_f::static_volume_ptr block(pool, mes); // 3.2 将块绑定为文件区域 bfs_f::file_agent_ptr region( file, i * 1024, 512, block.get_agent_ptr(), mes ); // 3.3 从文件加载到块 region.pull_cache_from_bin_file(mes); // 3.4 从块加载到业务对象 bmms_f::agent_ptr entry_agent(&entries[i], sizeof(Entry)); block.get_agent_ptr().load_to_agent_ptr( 0, sizeof(Entry), entry_agent, 0, true, mes ); // 3.5 业务处理 entries[i].update(); // 3.6 写回块 block.get_agent_ptr().store_from_agent_ptr( entry_agent, 0, sizeof(Entry), 0, true, mes ); // 3.7 刷回文件 region.push_cache_to_bin_file(mes); // 3.8 块自动归还(static_volume_ptr析构) } ``` **语义**:每个 `Entry` 独立处理,资源自动管理,数据流动路径清晰可追踪。 --- ## 关键设计点总结 1. **类型安全**:业务代码操作的是 `T`,代理指针只是桥梁 2. **统一语义**:`load/store` 系列函数签名完全一致 3. **显式控制**:没有隐式刷盘、隐式分配 4. **零拷贝**:文件缓存直接使用池中内存 5. **逻辑隔离**:`part` 提供轻量级视图,支持空洞和超用 6. **强制错误消费**:`mes::res` 确保错误被处理 ```cpp // 典型的数据流动模式 T data; bmms_f::agent_ptr agent(&data, sizeof(T)); // 文件 → agent → data file.load_to_agent_ptr(offset, sizeof(T), agent, 0, true, mes); data.modify(); file.store_from_agent_ptr(agent, 0, sizeof(T), offset, true, true, mes); // 或者 cache.load_to_agent_ptr(offset, sizeof(T), agent, 0, true, mes); data.modify(); cache.store_from_agent_ptr(agent, 0, sizeof(T), offset, true, mes); cache.push_cache_to_bin_file(mes); ``` ### 示例3:带错误检查的结果包 ```cpp import MES; mes::res> res({1, 2, 3, 4, 5}); // 设置必须检查的错误 mes::a_mes error = /* 某个错误 */; res.set_err(error, true); // true = 必须检查 // 正确做法:先检查错误 if (res.has_err()) { mes::a_mes e = res.get_err(); // 消费错误 e.out(); } // 现在可以安全获取结果 auto vec = res.move_result(); ``` # 爽点解析 ## 🎯 爽点一:类型安全不丢,语义统一不变 ```cpp // 普通C++对象,该咋用咋用 Config cfg; cfg.version = 2; // 直接访问成员 // 代理指针只是个"视图",不干扰业务逻辑 bmms_f::agent_ptr cfg_agent(&cfg, sizeof(Config)); // 文件读写,语义完全一致 file.load_to_agent_ptr(0, sizeof(Config), cfg_agent, 0, true, mes); // 业务代码照常 cfg.upgrade(); file.store_from_agent_ptr(cfg_agent, 0, sizeof(Config), 0, true, true, mes); ``` **对比传统方案**: - ❌ mmap:得用指针算术,类型不安全 - ❌ 序列化:得写一堆to_bytes/from_bytes - ❌ fread/fwrite:得自己算偏移、大小 - ✅ 本方案:对象还是对象,文件操作是"附赠"的 --- ## 🎯 爽点二:内存池和文件缓存,写法一模一样 ```cpp // 内存池分配 bmms_f::static_volume_ptr block(vol, mes); // 文件区域视图 bfs_f::file_agent_ptr cache(file, offset, size, block.get_agent_ptr(), mes); // 加载数据到对象 cache.load_to_agent_ptr(0, sizeof(T), obj_agent, 0, true, mes); // 改对象 obj.update(); // 写回缓存 cache.store_from_agent_ptr(obj_agent, 0, sizeof(T), 0, true, mes); // 刷盘 cache.push_cache_to_bin_file(mes); ``` **爽在哪**?—— **思维不切换**。文件也好,内存也好,代码长得一模一样。 --- ## 🎯 爽点三:`part` 让逻辑空间无限大 ```cpp // 物理只有1000个块 auto phys = std::make_shared(64, 1000, ...); // 但你可以有三个"虚拟视图" bmms_f::static_volume_part session(phys, 2000, allow_over_use, ...); bmms_f::static_volume_part cache(phys, 5000, allow_over_use, ...); bmms_f::static_volume_part temp(phys, 3000, allow_over_use, ...); // 写代码时根本不用想物理内存 for(int i = 0; i < 2000; i++) { session.store_from_void_ptr(&data, 64, i*64, true, mes); // 前1000次成功,1001次开始返回"物理不足"错误 } ``` **爽在哪**?—— **物理和逻辑解耦**。你可以先设计逻辑架构,物理不够自然会报错,而不是提前算死。 --- ## 🎯 爽点四:空洞自动管理,上层无感 ```cpp // 分配一堆 for(int i = 0; i < 100; i++) { part.store_from_void_ptr(&data, 64, i*64, true, mes); } // 释放中间的一些 part.free_block(30); part.free_block(31); part.free_block(32); // 后来者自动复用空洞 part.store_from_void_ptr(&new_data, 64, 30*64, true, mes); // 自动重新分配 // 完全不用维护空闲链表 ``` **爽在哪**?—— **内存管理是 infrastructure 的事**,业务代码只需要 `store` 和 `free_block`。 --- ## 🎯 爽点五:错误必须消费,否则拿不到结果 ```cpp mes::res> res({1,2,3}); res.set_err(some_error, true); // 标记为必须检查 // 忘了检查? auto vec = res.move_result(); // 进程终止!MODC:6 MESC:... // 正确做法 if(res.has_err()) { auto e = res.get_err(); // 消费错误 e.out(); } auto vec = res.move_result(); // 安全 ``` **爽在哪**?—— **错误不会悄悄溜过**。要么显式处理,要么程序死给你看。 --- ## 🎯 爽点六:资源生命周期自动管理 ```cpp { auto vol = std::make_shared(...); { bmms_f::static_volume_ptr block(vol, mes); // 分配块 bfs_f::file_agent_ptr cache(file, offset, size, block.get_agent_ptr(), mes); // ... 干活 ... } // block析构 → 块自动归还池子 // cache析构 → 自动解绑定(脏页?自动写回,但是不管结果) } // vol的最后一个shared_ptr析构 → 物理内存释放 ``` **爽在哪**?—— **RAII 的威力**。分配、释放、绑定、解绑,全自动。 --- ## 🎯 爽点七:数据流动路径一目了然 ```cpp // 数据从磁盘到寄存器的完整路径,每一行都清晰 // 1. 文件 → 缓存 cache.pull_cache_from_bin_file(mes); // 2. 缓存 → 业务对象 cache.load_to_agent_ptr(offset, sizeof(T), obj_agent, 0, true, mes); // 3. 业务对象 → 寄存器 obj_agent.load_to_void_ptr(field_offset, sizeof(field), ®, true, mes); // 4. 改寄存器 reg++; // 5. 寄存器 → 业务对象 obj_agent.store_from_void_ptr(®, sizeof(field), field_offset, true, mes); // 6. 业务对象 → 缓存 cache.store_from_agent_ptr(obj_agent, 0, sizeof(T), offset, true, mes); // 7. 缓存 → 文件 cache.push_cache_to_bin_file(mes); ``` **爽在哪**?—— **没有黑盒**。数据怎么流、流到哪、谁改了它,全都看得见。 --- ## 🎯 爽点八:模板自由,编译期多态 ```cpp template void process_object(bfs_f::file_agent_ptr& cache, size_t offset, T& obj) { bmms_f::agent_ptr obj_agent(&obj, sizeof(T)); cache.load_to_agent_ptr(offset, sizeof(T), obj_agent, 0, true, mes); obj.process(); // T 自己的方法 cache.store_from_agent_ptr(obj_agent, 0, sizeof(T), offset, true, mes); } // 任何类型都能用 Config cfg; Packet pkt; Record rec; process_object(cache, 0, cfg); process_object(cache, 1024, pkt); process_object(cache, 2048, rec); ``` **爽在哪**?—— **真正的泛型编程**。一套代码,服务所有类型。 --- ## 总结 这套系统的爽点在于: 1. **类型安全**:业务代码操作的是真实对象,不是字节数组 2. **语义统一**:内存和文件操作长得一模一样,脑负担低 3. **逻辑隔离**:`part` 让你在逻辑层面设计,物理不够会报错 4. **自动管理**:空洞、生命周期、错误消费,全是 infrastructure 的事 5. **路径清晰**:数据流动的每一步都显式写出,没有隐式魔法 6. **强制安全**:错误必须消费,否则拿不到结果 **用这套写代码的感觉**:就像写普通C++,但"附赠"了内存池、文件缓存、零拷贝、错误检查。该是对象的地方就是对象,该是文件的地方就是文件,但操作它们的方法**一模一样**。 **爽!** --- ## 📚 公共方法简介 ### BMMS 模块 #### `agent_ptr` 类(代理指针) | 方法 | 描述 | |------|------| | `agent_ptr(void* ptr, size_t size)` | 从原始指针和大小构造代理指针 | | `load(load_begin, load_size, save_agent, store_begin, safe)` | 将本区域数据读入另一代理指针 | | `store(load_agent, load_begin, load_size, store_begin, safe)` | 从另一代理指针读数据写入本区域 | | `load_to_void_ptr(load_begin, load_size, dest_ptr, safe)` | 将本区域数据读入原始指针 | | `store_from_void_ptr(src_ptr, load_size, store_begin, safe)` | 从原始指针读数据写入本区域 | | `clear()` | 清空整个区域 | | `clear_range(begin, size)` | 清空指定范围 | | `get_void_ptr(ptr_out)` | 获取原始指针 | | `get_is_null(is_null_out)` | 检查是否为空 | | `get_size(size_out)` | 获取区域大小 | | `get_begin(begin_out)` | 获取起始地址 | | `get_end(end_out)` | 获取结束地址 | | `get_check_range_bool(begin, size, is_valid_out)` | 检查范围是否有效 | #### `static_volume` 类(静态内存卷) | 方法 | 描述 | |------|------| | `static_volume(block_size, block_count, init_type, alignment, mes_out)` | 构造静态内存卷 | | `new_block(agent_ptr_out, mes_out)` | 分配一个新块 | | `delete_block(agent_ptr_in)` | 释放块回回收栈 | | `get_is_init()` | 检查是否已初始化 | | `get_block_count_max()` | 获取最大块数 | | `get_free_block_count()` | 获取空闲块数 | | `get_block_size()` | 获取块大小 | #### `static_volume_ptr` 类(RAII块指针) | 方法 | 描述 | |------|------| | `static_volume_ptr(volume_shared_ptr, mes_out)` | 从静态卷构造,自动分配一个块 | | `clear()` | 清空整个块 | | `clear_range(begin, size)` | 清空块内指定范围 | | `load(...)` | 同agent_ptr语义 | | `store(...)` | 同agent_ptr语义 | | `load_to_void_ptr(...)` | 同agent_ptr语义 | | `store_from_void_ptr(...)` | 同agent_ptr语义 | | `get_agent_ptr()` | 获取底层代理指针 | #### `static_volume_part` 类(静态卷逻辑分区) | 方法 | 描述 | |------|------| | `static_volume_part(volume, block_count, init_type, control_type, mes_out)` | 创建静态卷的逻辑分区 | | `clear()` | 清空整个分区 | | `clear_range(begin, size)` | 清空分区内指定范围 | | `resize(block_count, mes_out)` | 调整分区大小 | | `free_block(block_index)` | 释放指定块(产生空洞) | | `free_range(begin, size)` | 释放指定范围块 | | `load(...)` | 同agent_ptr语义 | | `store(...)` | 同agent_ptr语义 | | `load_to_void_ptr(...)` | 同agent_ptr语义 | | `store_from_void_ptr(...)` | 同agent_ptr语义 | | `get_total_size()` | 获取分区总大小(字节) | | `get_block_count_max()` | 获取最大块数 | | `get_block_size()` | 获取块大小 | | `get_block_count_used()` | 获取已用块数 | | `get_block_ptr(index, agent_out, is_null_out)` | 获取指定块的代理指针 | #### `free_volume` 类(动态内存卷) | 方法 | 描述 | |------|------| | `free_volume(block_size, block_count, init_type, alignment, mes_out)` | 构造动态内存卷 | | `new_block(agent_ptr_out, index_out, mes_out)` | 分配一个新块 | | `delete_block(agent_ptr_in, index_in)` | 释放块 | | `free_unused_block(index)` | 释放空闲块的物理内存 | | `free_range(begin, size)` | 释放范围内所有空闲块的物理内存 | | `free_all_unused_blocks()` | 释放所有空闲块的物理内存 | | `get_is_init()` | 检查是否已初始化 | | `get_block_count_max()` | 获取最大块数 | | `get_block_count_used()` | 获取已用块数 | | `get_free_block_count()` | 获取空闲块数 | | `get_block_size()` | 获取块大小 | #### `free_volume_ptr` 类(动态卷RAII指针) | 方法 | 描述 | |------|------| | `free_volume_ptr(volume_shared_ptr, mes_out)` | 从动态卷构造,自动分配一个块 | | `clear()` | 清空整个块 | | `clear_range(begin, size)` | 清空块内指定范围 | | `load(...)` | 同agent_ptr语义 | | `store(...)` | 同agent_ptr语义 | | `load_to_void_ptr(...)` | 同agent_ptr语义 | | `store_from_void_ptr(...)` | 同agent_ptr语义 | | `get_index()` | 获取块索引 | | `get_agent_ptr()` | 获取底层代理指针 | #### `free_part` 类(自由块逻辑分区) | 方法 | 描述 | |------|------| | `free_part(block_size, block_count, init_type, mes_out)` | 创建自由块逻辑分区 | | `clear()` | 清空整个分区 | | `clear_range(begin, size)` | 清空分区内指定范围 | | `resize(block_count, mes_out)` | 调整分区大小 | | `free_block(index)` | 释放指定块 | | `free_range(begin, size)` | 释放指定范围块 | | `load(...)` | 同agent_ptr语义 | | `store(...)` | 同agent_ptr语义 | | `load_to_void_ptr(...)` | 同agent_ptr语义 | | `store_from_void_ptr(...)` | 同agent_ptr语义 | | `get_total_size()` | 获取分区总大小 | | `get_block_count_max()` | 获取最大块数 | | `get_block_size()` | 获取块大小 | | `get_block_count_used()` | 获取已用块数 | | `get_block_ptr(index, agent_out, is_null_out)` | 获取指定块的代理指针 | --- ### BFS 模块 #### `bin_file` 类(二进制文件) | 方法 | 描述 | |------|------| | `bin_file(path, size, init_type, mes_out)` | 构造二进制文件对象 | | `open(path, size, init_type, mes_out)` | 打开文件 | | `flush()` | 刷新缓冲区 | | `close(mes_out)` | 关闭文件 | | `resize(size, mes_out)` | 调整文件大小 | | `clear(mes_out)` | 清空整个文件 | | `clear_range(begin, size, mes_out)` | 清空文件指定范围 | | `save_as(path, mes_out)` | 另存为 | | `load(load_begin, load_size, dest_file, store_begin, safe, flush, mes_out)` | 从本文件读数据写入另一文件 | | `store(src_file, load_begin, load_size, store_begin, safe, flush, mes_out)` | 从另一文件读数据写入本文件 | | `load_to_agent_ptr(load_begin, load_size, dest_agent, store_begin, safe, mes_out)` | 从文件读数据到代理指针 | | `store_from_agent_ptr(src_agent, load_begin, load_size, store_begin, safe, flush, mes_out)` | 从代理指针读数据写入文件 | | `load_to_void_ptr(load_begin, load_size, dest_ptr, safe, mes_out)` | 从文件读数据到原始指针 | | `store_from_void_ptr(src_ptr, load_size, store_begin, safe, mes_out)` | 从原始指针读数据写入文件 | | `__file_size__()` | 获取文件大小 | | `__self_begin__()` | 获取文件起始偏移(0) | | `__self_end__()` | 获取文件结束偏移 | #### `file_agent_ptr` 类(文件缓存代理) | 方法 | 描述 | |------|------| | `file_agent_ptr(bin_file, begin, size, cache_agent, mes_out)` | 构造文件区域视图 | | `clear(mes_out)` | 清空整个缓存 | | `clear_range(begin, size, mes_out)` | 清空缓存指定范围 | | `push_cache_to_bin_file(mes_out)` | 将脏缓存刷回文件 | | `pull_cache_from_bin_file(mes_out)` | 从文件加载数据到缓存 | | `load(load_begin, load_size, dest_fap, store_begin, safe, mes_out)` | 从本缓存读数据写入另一文件代理 | | `store(src_fap, load_begin, load_size, store_begin, safe, mes_out)` | 从另一文件代理读数据写入本缓存 | | `load_to_agent_ptr(load_begin, load_size, dest_agent, store_begin, safe, mes_out)` | 从缓存读数据到代理指针 | | `store_from_agent_ptr(src_agent, load_begin, load_size, store_begin, safe, mes_out)` | 从代理指针读数据写入缓存 | | `load_to_void_ptr(load_begin, load_size, dest_ptr, safe, mes_out)` | 从缓存读数据到原始指针 | | `store_from_void_ptr(src_ptr, load_size, store_begin, safe, mes_out)` | 从原始指针读数据写入缓存 | | `get_is_inited(is_inited_out)` | 获取初始化状态 | | `get_cache_begin_about_bin_file(begin_out)` | 获取缓存对应文件的起始偏移 | | `get_cache_agent_ptr(agent_out)` | 获取底层缓存代理指针 | | `get_cache_raw_ptr(ptr_out)` | 获取缓存原始指针 | | `get_cache_size(size_out)` | 获取缓存大小 | | `get_dirty_flag(is_dirty_out)` | 获取脏页标记 | | `get_associated_bin_file_shared_ptr(file_out)` | 获取关联的文件对象 | | `get_managed_file_size(size_out, mes_out)` | 获取管理的文件区域大小 | | `get_cache_used_size(size_out, mes_out)` | 获取缓存已用大小 | | `check_file_still_valid(is_valid_out, mes_out)` | 检查关联文件是否仍有效 | | `calculate_cache_position(file_pos, cache_pos_out, is_mappable_out, mes_out)` | 文件位置映射到缓存位置 | | `calculate_file_position(cache_pos, file_pos_out, is_mappable_out, mes_out)` | 缓存位置映射回文件位置 | #### 目录控制(`dir_control` 命名空间) | 方法 | 描述 | |------|------| | `add_dir(path, mes_out)` | 创建目录 | | `del(path, mes_out)` | 删除文件或目录 | | `get_dir_list(path, dir_list_out, mes_out)` | 获取子目录列表 | | `get_list_file(path, file_list_out, mes_out)` | 获取文件列表 | | `get_path_is_excited(path, is_excited_out, mes_out)` | 检查路径是否存在 | | `get_is_dir(path, is_dir_out, mes_out)` | 检查是否为目录 | | `get_is_file(path, is_file_out, mes_out)` | 检查是否为文件 | | `get_accessible(path, accessible_out, mes_out)` | 检查路径是否可访问 | | `rename(old_path, new_path, mes_out, overwrite)` | 重命名文件或路径 | --- ### MES 模块 #### `a_mes` 类(消息) | 方法 | 描述 | |------|------| | `a_mes(mode_code, line, message)` | 构造消息 | | `out()` | 输出消息 | #### `res` 类(带消息的结果包) | 方法 | 描述 | |------|------| | `res(const T& result)` | 从结果构造 | | `res(T& result, bool move_data)` | 从结果构造(可选移动) | | `clear()` | 清空包内容 | | `set_time_or_temp(time)` | 设置时间/临时标记 | | `set_sug(mes, must_chk)` | 设置建议(必须检查标记) | | `set_war(war, must_chk)` | 设置警告 | | `set_err(err, must_chk)` | 设置错误 | | `set_dynamic_mes(mes, must_chk)` | 设置动态消息 | | `set_call_chain(file, func, line)` | 设置调用链 | | `freeze()` | 冻结(禁止再设置消息) | | `unfreeze()` | 解冻 | | `has_freeze()` | 检查是否冻结 | | `has_sug()` | 检查是否有建议 | | `has_war()` | 检查是否有警告 | | `has_err()` | 检查是否有错误 | | `has_dynamic_mes()` | 检查是否有动态消息 | | `has_call_chain()` | 检查是否有调用链 | | `get_sug_must_chk()` | 获取建议必须检查标记 | | `get_war_must_chk()` | 获取警告必须检查标记 | | `get_err_must_chk()` | 获取错误必须检查标记 | | `get_dynamic_mes_must_chk()` | 获取动态消息必须检查标记 | | `get_time_or_temp()` | 获取时间/临时标记 | | `get_sug()` | 获取建议(消费must_chk) | | `get_war()` | 获取警告 | | `get_err()` | 获取错误 | | `get_dynamic_mes()` | 获取动态消息 | | `get_call_chain_layer_depth()` | 获取调用链深度 | | `get_call_chain(layer)` | 获取指定层调用链 | | `move_result()` | 移动结果(需消费所有must_chk) | | `get_result()` | 获取结果副本 |