Rust使用bincode序列化结构体写入文件后反序列化结果异常
问题核心原因
serialize_to_file函数每次调用都会清空已有文件内容
你使用了File::create(file_name).unwrap()打开文件进行写入,该方法的默认行为是:如果目标文件已存在,直接将文件长度截断为0,清空所有原有数据。
你循环4次调用序列化函数的实际执行效果如下:
- 第1次(id=0):新建文件,偏移0位置写入bar=0,文件前8字节为0
- 第2次(id=1):清空已有文件,偏移8位置写入bar=1,操作系统自动给未写入的07字节填充0,此时文件815字节为1
- 第3次(id=2):再次清空文件,偏移16位置写入bar=2,未写入的015字节自动填充为0,此时文件1623字节为2
- 第4次(id=3):第三次清空文件,偏移24位置写入bar=3,未写入的023字节自动填充为0,此时文件2431字节为3
最终文件前24字节全部为0,最后8字节为3,和你实际读取的结果完全匹配。
- 存在短写风险
你直接调用file.write(&encoded),该方法不保证会写入全部字节,可能出现只写入部分数据的问题,应该替换为write_all保证完整写入。
修复代码
修改后的 serialize_to_file 函数如下:
fn serialize_to_file(id: u64, file_name: &str) -> usize { // 用OpenOptions打开文件,不截断原有内容,支持创建、写入 let mut file = std::fs::OpenOptions::new() .create(true) .write(true) .open(file_name) .unwrap(); let foo = Foo { bar: id }; let encoded: Vec<u8> = bincode::serialize(&foo).unwrap(); file.seek(SeekFrom::Start(id * PAGE_SIZE as u64)).unwrap(); // 用write_all保证全部写入 file.write_all(&encoded).unwrap(); encoded.len() }
修改后运行即可得到预期结果。
内容的提问来源于stack exchange,提问作者TheQuestioner
相关产品推荐
相关产品推荐

