在 Rust 中如何使用单一方法创建一个文件及其父目录?

24

我是否可以使用OpenOptions或类似的单一方法来创建文件及其父目录并打开它?

这只会创建一个新文件,如果我的路径包括不存在的目录,则不起作用:

pub fn save_file(file_path: String) -> Result<(), Error> {
    let mut db_file = OpenOptions::new()
        .create(true)
        .append(true)
        .open(file_path)?;
    db_file.write_all(b"some content")?;
    Ok(())
}

我也遇到了同样的问题,但是我的应用程序使用Tauri框架。奇怪的是,在开发环境中它可以工作,但在打包后的应用程序输出(目标发布)中它却无法写入文件。 - Sydalmighty
1个回答

29

我找不到一个单一的方法来完成这个任务,但以下是如何为给定文件创建父目录(等)的两种方法(如果不计算 let path = … )。

let path = std::path::Path::new("/home/roger/foo/bar/baz.txt");
let prefix = path.parent().unwrap();
std::fs::create_dir_all(prefix).unwrap();

1
这可能会受到TOCTOU攻击,需要进行开发以确保正确性。 - mcarton
5
虽然您的担忧是正确的,但他们没有询问任何与安全有关的问题。提供一个应对每种情况的完整解决方案,在经过一些健全性检查后仍然包含这个确切的代码,是完全没有意义的。他们询问如何做到这一点,这正是你要做的,我们的工作不是确保他们编写的代码实际上是安全的,尽管我同意在代码上面或其中提到安全相关问题是一个好的建议,这就是为什么您可以按照自己的需要进行编辑 :) - user11877195
10
这里似乎没有C,只有U。你总是无条件地调用create_dir_all - justinas
1
@Sahsahae 我不同意。如果这段代码存在TOCTOU竞争条件,那么它是错误的,无论是否存在安全问题。那种类型的竞争条件是一个漏洞。但是这段代码根本没有竞争条件。 - Sven Marnach
我正在尝试找到这里的C,因为我想确保自己不会成为TOCTOU攻击的受害者。据我所知,@justinas在这个例子中是正确的,因为该例子被无条件地调用。 - Alexis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接