不追加就无法写入文件

Cannot write file without appending to it

我正在尝试写入一个 json 文件,但它一直附加到文件而不是覆盖它,即使我将附加设置为 false

我做错了什么?谢谢

use serde::{Deserialize, Serialize};
use serde_json::{json, Map, Value};
use sha2::{Digest, Sha256};
use std::{error::Error, fs::{OpenOptions}, io::prelude::*};

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Session {
    username: String,
    hashed_ip: String,
    session_id: String,
    expires_at: u64,
}

impl Session {
    pub fn add(&self) -> Result<(), Box<dyn Error>> {
        let session_path = "./storage/sessions/current_sessions.json";
        let mut file = OpenOptions::new()
            .write(true)
            .read(true)
            .append(false)
            .open(session_path)?;
        let mut file_content = String::new();
        file.read_to_string(&mut file_content)?;
        let sessions_value = serde_json::from_str(&file_content)?;
        let mut sessions;
        if let Value::Object(map) = sessions_value {
            sessions = map;
        } else {
            sessions = Map::new();
        }
        let clean = SessionClean::from_session(self);
        sessions.insert(self.session_id.clone(), serde_json::to_value(clean)?);
        println!("{}", Value::Object(sessions.clone()).to_string());
        file.write_all(Value::Object(sessions.clone()).to_string().as_str().as_bytes())?;
        file.flush()?;
        Ok(())
    }
}

预期结果为:

{"some_session_id":{"expires_at":1646583038,"hashed_ip":"1ea442a134b2a184bd5d40104401f2a37fbc09ccf3f4bc9da161c6099be3691d","username":"Someone"}}

相反,这发生了:

{}{"some_session_id":{"expires_at":1646583038,"hashed_ip":"1ea442a134b2a184bd5d40104401f2a37fbc09ccf3f4bc9da161c6099be3691d","username":"Someone"}}

这里是整个代码:https://github.com/Siriusmart/siribot-registry

您在写入文件之前正在读取文件。这使得光标位于文件的末尾。您必须在写入之前将其设置为初始位置。例如使用 Seek::rewind

文档中的示例:

use std::io::{Read, Seek, Write};
use std::fs::OpenOptions;

let mut f = OpenOptions::new()
    .write(true)
    .read(true)
    .create(true)
    .open("foo.txt").unwrap();

let hello = "Hello!\n";
write!(f, "{}", hello).unwrap();
f.rewind().unwrap();

let mut buf = String::new();
f.read_to_string(&mut buf).unwrap();
assert_eq!(&buf, hello);