hwiechers
hwiechers

Reputation: 14995

Is there any way to create and open a file if it doesn't exist but fail otherwise?

It looks like OpenOptions does not support this scenario and an existing file will either be truncated or overwritten.

Upvotes: 31

Views: 26738

Answers (4)

David Roundy
David Roundy

Reputation: 1766

As of Rust 1.9.0, there is OpenOptions::create_new which enables you to safely and atomically ensure that you are creating a new file. An Err is returned if the file already exists. If .create_new(true) is set, .create() and .truncate() are ignored.

If you want to create a new file, or open it if it already exists, use OpenOptions::create.

Upvotes: 30

dessalines
dessalines

Reputation: 7372

I've found this to work best:

use std::fs;
use std::fs::OpenOptions;
use std::io::prelude::*;

if Path::new(file).exists() {
  fs::remove_file(file).unwrap();
}

File::create(TMP_ADDS).unwrap();
    let mut file = OpenOptions::new()
        .create_new(true)
        .write(true)
        .append(true)
        .open(file)
        .unwrap();

    if let Err(e) = writeln!(file, "{}", line) {
        eprintln!("Couldn't write to file: {}", e);
    }

Upvotes: 13

Matthieu M.
Matthieu M.

Reputation: 299890

It is possible in C11, or by using low-level OS API functions directly.

If you use C11, fopen allows you to open the file in "wx" mode.

Otherwise, on Linux, one should pass both O_CREAT and O_EXCL to the open(3) function. Or, on Windows, pass CREATE_NEW to the dwCreationDisposition parameter of the CreateFile() function.


EDIT: I originally missed the fact that the open function had been updated in C11.

Upvotes: 2

Not Important
Not Important

Reputation: 285

Update: As Mathieu David pointed out in the comments. exists() from std::path::Path can be used to check if a path exists.

Old Answer:

In C, checking if a file name/path exists is usually done with:

! access(filename, F_OK)

access returns 0 if the file exists, provided that you have the needed permissions.

I did a quick search for a native Rust equivalent and couldn't find anything. So, you may need to depend on libc::access for this.

Upvotes: 1

Related Questions