OpenOptions
std::fs::OpenOptions (also accessible via File::options()) is a builder struct that configures the exact flags and permissions used to open or create a File. Unlike File::open (read-only) and File::create (write-only + truncate), OpenOptions unlocks simultaneous read-write access, non-truncating writes, atomic exclusive creation (create_new), and OS-specific file flags (such as Unix octal mode 0o600).
All Configuration Flags on OpenOptions
Every flag on OpenOptions defaults to false. You must enable at least one of .read(true), .write(true), or .append(true) before calling .open(path) (otherwise .open() returns ErrorKind::InvalidInput):
| Builder Method | Requires | OS Flag Equivalent (POSIX) | Behavior |
|---|---|---|---|
.read(true) |
— | O_RDONLY / O_RDWR |
Opens file with read access |
.write(true) |
— | O_WRONLY / O_RDWR |
Opens file with write access (does not truncate existing bytes unless .truncate(true) is also set!) |
.append(true) |
— | O_WRONLY | O_APPEND |
Positions every write atomically at the current end of the file |
.truncate(true) |
.write(true) |
O_TRUNC |
Truncates an existing file to 0 bytes upon opening |
.create(true) |
.write(true) or .append(true) |
O_CREAT |
Creates the file if missing; opens the existing file if present |
.create_new(true) |
.write(true) or .append(true) |
O_CREAT | O_EXCL |
Atomically creates the file if missing; fails with AlreadyExists if present (overrides .create and .truncate) |
Common File::options() Combinations
Standard Library Shorthands Desugared to `File::options()`:
File::open(p) <===> File::options().read(true).open(p)
File::create(p) <===> File::options().write(true).create(true).truncate(true).open(p)
File::create_new(p) <===> File::options().read(true).write(true).create_new(true).open(p)
In-Place Read-Modify-Write Without Truncating:
File::options().read(true).write(true).create(true).open(p)
use std::fs::{self, File};
use std::io::{self, Read, Seek, SeekFrom, Write};
fn main() -> io::Result<()> {
let path = std::env::temp_dir().join("rust_ch50_open_options.bin");
let _ = fs::remove_file(&path);
// Open with BOTH `.read(true)` and `.write(true)` + `.create(true)` (no `.truncate(true)`!):
let mut file = File::options()
.read(true)
.write(true)
.create(true)
.open(&path)?;
file.write_all(b"0000_PAYLOAD")?;
// Patch the first 4 bytes in place without truncating `_PAYLOAD`:
file.seek(SeekFrom::Start(0))?;
file.write_all(b"2026")?;
// Read the entire patched file back through the same `File` handle:
file.rewind()?;
let mut result = String::new();
file.read_to_string(&mut result)?;
drop(file);
fs::remove_file(&path)?;
println!("in-place patched content: {:?}", result);
Ok(())
}
in-place patched content: "2026_PAYLOAD"
Setting Restricted Unix Creation Permissions (OpenOptionsExt::mode)
When creating a file containing sensitive secrets or private keys on Unix, setting permissions after File::create leaves a brief window where the file exists with default umask permissions. Using std::os::unix::fs::OpenOptionsExt::mode(0o600) passes 0o600 directly to the open() syscall so the file is born readable/writable only by its owner from the instant of creation!