如何在写入文件之前删除文件的内容?

How to delete the contents of a file before writing to it?

我写了一个机器人,它每隔一段时间就执行一些网络查询,并将最新状态转储到存储在磁盘上的文件中。这是我的代码:

let log_file = OpenOptions::new()
    .read(true)
    .write(true)
    .create(true)
    .open(&log_file_name)
    .unwrap();
serde_json::to_writer(
    log_file,
    &State {
        foo: self.foo,
        bar: self.bar
    },
)
.unwrap();

问题是,有时最新状态 json 的大小会小于先前状态 JSON 的大小。这使得比新状态 JSON 长的先前状态 JSON 的部分保留在日志文件中:

{"foo": 1,"bar": 2}"baz": 3}

在上面的例子中,"baz": 3}是前一个状态JSON的剩余数据。

问题是:我如何重写代码,以便我先刷新文件的所有内容,然后写入新状态json?

我知道删除文件是一种解决方案,但我不想这样做。

使用.truncate()。示例:

let log_file = OpenOptions::new()
    .read(true)
    .write(true)
    .create(true)
    .truncate(true) // added here
    .open(&log_file_name)
    .unwrap();

您还需要 truncate 标志,如果文件已经存在,这会导致文件被截断为长度 0。此外,您应该删除 read 标志,因为您实际上并没有从日志文件中读取。

由于writecreatetruncate是很常见的标志组合,所以有一个捷径:你不需要使用更底层的OpenOptions 接口,可以改用 File::create():

let log_file = File::create(&log_file_name).unwrap();

File::create() 的实现只是使用 OpenOptions:

拼写出长版本
pub fn create<P: AsRef<Path>>(path: P) -> io::Result<File> {
    OpenOptions::new().write(true).create(true).truncate(true).open(path.as_ref())
}