rust - 使用 Append(false) 写入文件无法按预期工作

标签 rust serde

我正在学习使用 Rust 编程,并决定构建一个 CLI 来管理我的个人图书馆。在进一步进行之前,我仍在进行概念的快速验证,因此我掌握了我需要工作的准系统。

我正在使用 std::fsserde_json 将数据保存到名为“books.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(())
}

关于rust - 使用 Append(false) 写入文件无法按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58667628/

相关文章:

rust - 从 map 中获得暂时的值(value)

python - 如何在 Mac 上安装 Jupyter 的 Rust?

rust - 为什么我不能在索引到不可变的 Vec<RefCell> 后调用 borrow_mut()?

rust - 使用 serde,是否可以反序列化为实现类型的结构?

rust - 如何延迟未命名对象的销毁?

typeclass - Rust:使用特征/类型类来实现通用数字函数

xml - 为什么在使用 serde-xml-rs 反序列化 XML 时出现错误 "missing field",即使该元素存在?

serialization - 如何在不包含枚举变体名称的情况下序列化枚举?

rust - <'_> 未实现特征 `Serialize`

json - 如何将字节流从 reqwest 响应反序列化为 JSON?