272. fs::create_dir_all — mkdir -p Without the exists() Check
fs::create_dir fails if the parent is missing and fails if the directory already exists. create_dir_all handles both — recursive and idempotent in one call.
The single-level version trips over both ends of the problem:
| |
So people reach for the guard:
| |
That’s a check-then-act race (bite 270 again): another process can create the directory between the check and the call, and you still can’t build a nested path in one go.
create_dir_all is the whole fix:
| |
It creates every missing component along the path, and it returns Ok when the directory already exists — no exists() probe, no AlreadyExists special-casing, safe to call on every startup.
Three details worth knowing:
- It’s concurrency-tolerant. If another thread or process creates one of the components mid-walk,
create_dir_allshrugs and keeps going. Theexists()guard can’t promise that. - A file in the way is still an error. If
cache/imagesexists but is a regular file, you get an error instead of silent breakage — exactly what you want. - It won’t touch what’s already there. Permissions of existing directories are left alone; only newly created components get the default (or
DirBuilder-configured) mode.
Same moral as the rest of this filesystem run: don’t interrogate the filesystem and then act on the answer — call the operation that already handles every case.