pub fn rename_noreplace<P: AsRef<Path>, Q: AsRef<Path>>(
from: P,
to: Q,
) -> Result<()>rename_noreplace #161427)Expand description
Renames a file or directory to a new name, returning AlreadyExists if to already
exists.
Unlike fs::rename, the destination is never overwritten. The check happens as part of the
same operation, which avoids check-then-rename races.
If the system crashes in the middle, it may be possible to end up with both copies of the file existing, but it should not be possible to end up with zero copies, or with a half-written file.
This will not work if the new name is on a different mount point.
§Platform-specific behavior
This function currently corresponds to:
- renameat2 with
RENAME_NOREPLACEon Linux and Android renamex_npwithRENAME_EXCLon Apple platforms- MoveFileExW without the
MOVEFILE_REPLACE_EXISTINGflag, with a fallback toSetFileInformationByHandle, on Windows linkfollowed byunlinkon other Unix platforms and on WASI- Otherwise, this function returns
Unsupported
The link and unlink fallback is also used at runtime on Linux, Android and Apple platforms
when the kernel or the filesystem does not support the flag, so which of these applies can
differ between filesystems on the same machine.
Note that, this may change in the future.
§Errors
This function will return an error in the following situations, but is not limited to just these cases:
fromdoes not exist.- The user lacks permissions to view contents.
fromandtoare on separate filesystems.toalready exists.- The platform does not support this operation.
§Examples
#![feature(rename_noreplace)]
use std::fs;
use std::io::ErrorKind;
fn main() -> std::io::Result<()> {
// Renames a.txt to b.txt, b.txt does not exist yet.
fs::rename_noreplace("a.txt", "b.txt")?;
// b.txt exists now, so this fails instead of silently overwriting it.
let err = fs::rename_noreplace("c.txt", "b.txt").unwrap_err();
assert_eq!(err.kind(), ErrorKind::AlreadyExists);
Ok(())
}