如何用serde向RON数组文件追加Action枚举(适配大文件)
向RON数组文件追加Action枚举实例(大文件友好)
核心思路
RON数组的结构是[元素1, 元素2, ...],要追加元素无需加载整个文件,只需定位到末尾的],替换为, 新元素](保持格式对齐)即可。分两种场景处理:空文件初始化、已有文件追加。
1. 空文件初始化
如果文件不存在或为空,直接生成标准的RON数组结构,写入第一个元素:
use ron::ser::{to_string, PrettyConfig}; use std::fs::File; use std::io::Write; fn init_actions_file(action: &Action) -> std::io::Result<()> { // 统一格式配置,保证缩进和换行一致 let pretty_cfg = PrettyConfig::new() .indentor(" ".to_string()) .new_line("\n".to_string()); // 序列化单个Action并调整缩进,适配数组格式 let serialized_action = to_string(action, pretty_cfg)?; let array_content = format!("[{}]", serialized_action.replace('\n', "\n ")); let mut file = File::create("actions.ron")?; file.write_all(array_content.as_bytes())?; Ok(()) }
2. 向已有数组追加元素
通过文件指针定位到末尾的],跳过可能的换行/空格,写入新元素后重新闭合数组:
use ron::ser::{to_string, PrettyConfig}; use std::fs::OpenOptions; use std::io::{Seek, SeekFrom, Write}; fn append_action_to_file(action: &Action) -> std::io::Result<()> { let mut file = OpenOptions::new() .read(true) .write(true) .open("actions.ron")?; let file_len = file.metadata()?.len(); // 空文件直接调用初始化逻辑 if file_len == 0 { return init_actions_file(action); } // 从文件末尾倒找闭合方括号`]`的位置 let mut bracket_pos = file_len - 1; loop { let mut buf = [0u8; 1]; file.seek(SeekFrom::Start(bracket_pos))?; file.read_exact(&mut buf)?; if buf[0] == b']' { break; } else if bracket_pos == 0 { return Err(std::io::Error::new( std::io::ErrorKind::InvalidData, "目标文件不是合法的RON数组格式", )); } bracket_pos -= 1; } // 定位到`]`的位置,准备覆盖写入 file.seek(SeekFrom::Start(bracket_pos))?; // 序列化新元素,添加逗号和对齐缩进 let pretty_cfg = PrettyConfig::new() .indentor(" ".to_string()) .new_line("\n".to_string()); let serialized_action = to_string(action, pretty_cfg)?; let new_element = format!(",\n {}", serialized_action); // 写入新元素和闭合方括号 file.write_all(new_element.as_bytes())?; file.write_all(b"\n]")?; Ok(()) }
关键注意事项
- 格式一致性:始终使用相同的
PrettyConfig生成序列化字符串,确保缩进、换行符与数组格式匹配,避免反序列化失败。 - 并发安全:如果存在多线程/进程写入场景,需添加文件排他锁(可使用
fs2crate的FileExt::lock_exclusive),防止文件结构损坏。 - 错误防护:代码中加入了格式合法性检查,若文件不是标准RON数组会返回明确错误,避免破坏已有数据。
- 大文件适配:仅通过文件指针定位操作,无需加载整个文件到内存,完美适配超大文件场景。
内容的提问来源于stack exchange,提问作者dodo
相关产品推荐
相关产品推荐

