rust - 使用 Append(false) 写入文件未按预期工作
问题描述
我正在学习使用 Rust 编程,并决定构建一个 CLI 来管理我的个人库。在进一步研究之前,我仍在快速进行概念验证,所以我已经掌握了我需要工作的基础知识。
我正在使用 and 将数据保存到一个名为“books.json”的文件std::fs
中serde_json
。该程序在我第一次运行时运行良好,但在第二次运行时,它不是覆盖文件,而是附加数据(出于测试目的,它会添加同一本书两次)。
这是我到目前为止编写的代码。通过使用OpenOptions.append(false)
,当我写入文件时不应该覆盖文件吗?
use serde::{Deserialize, Serialize};
use serde_json::Error;
use std::fs;
use std::fs::File;
use std::io::Read;
use std::io::Write;
#[derive(Serialize, Deserialize)]
struct Book {
title: String,
author: String,
isbn: String,
pub_year: usize,
}
fn main() -> Result<(), serde_json::Error> {
let mut file = fs::OpenOptions::new()
.read(true)
.write(true)
.append(false)
.create(true)
.open("books.json")
.expect("Unable to open");
let mut data = String::new();
file.read_to_string(&mut data);
let mut bookshelf: Vec<Book> = Vec::new();
if file.metadata().unwrap().len() != 0 {
bookshelf = serde_json::from_str(&data)?;
}
let book = Book {
title: "The Institute".to_string(),
author: "Stephen King".to_string(),
isbn: "9781982110567".to_string(),
pub_year: 2019,
};
bookshelf.push(book);
let j: String = serde_json::to_string(&bookshelf)?;
file.write_all(j.as_bytes()).expect("Unable to write data");
Ok(())
}
两次运行程序后的books.json:
[{"title":"The Institute","author":"Stephen King","isbn":"9781982110567","pub_year":2019}]
[{"title":"The Institute","author":"Stephen King","isbn":"9781982110567","pub_year":2019},
{"title":"The Institute","author":"Stephen King","isbn":"9781982110567","pub_year":2019}]%
解决方案
Rust Discord 社区的成员指出,通过使用OpenOptions
,当我写文件时,文件指针会在文件末尾结束。他们建议我使用 fs::read 和 fs::write,这很有效。然后我添加了一些代码来处理文件不存在的情况。
然后该main()
函数需要看起来像这样:
fn main() -> std::io::Result<()> {
let f = File::open("books.json");
let _ = match f {
Ok(file) => file,
Err(error) => match error.kind() {
ErrorKind::NotFound => match File::create("books.json") {
Ok(fc) => fc,
Err(e) => panic!("Problem creating the file: {:?}", e),
},
},
};
let data = fs::read_to_string("books.json").expect("Unable to read file");
let mut bookshelf: Vec<Book> = Vec::new();
if fs::metadata("books.json").unwrap().len() != 0 {
bookshelf = serde_json::from_str(&data)?;
}
let book = Book {
title: "The Institute".to_string(),
author: "Stephen King".to_string(),
isbn: "9781982110567".to_string(),
pub_year: 2019,
};
bookshelf.push(book);
let json: String = serde_json::to_string(&bookshelf)?;
fs::write("books.json", &json).expect("Unable to write file");
println!("{}", &json);
Ok(())
}
推荐阅读
- r - 使用多个条件查找(或合并)2 个数据帧
- c# - 将 G Suite 驱动器文件和文件夹从一个域复制到另一个域
- python - 在集合中查找内容与在 python 中查找列表的速度
- node.js - 如何使用firebase函数刷新google oauth2上的令牌?
- amazon-web-services - 将 Schedule-ScheduledJob 注册为 LocalSystem 用户
- typescript - 尽管存在,但编译器“未找到”类型,而 IntelliSense 找到它们?
- python - Python For 循环输出列模式
- mongodb - MongoDB 查询索引扫描未按预期过滤
- python - Python中同目录HTML文件的解析
- python - python3 AttributeError:'int'对象没有属性'length'