library/std/src/fs.rs RUST 3,506 lines View on github.com → Search inside
File is large — showing lines 1–2,000 of 3,506.
1//! Filesystem manipulation operations.2//!3//! This module contains basic methods to manipulate the contents of the local4//! filesystem. All methods in this module represent cross-platform filesystem5//! operations. Extra platform-specific functionality can be found in the6//! extension traits of `std::os::$platform`.7//!8//! # Time of Check to Time of Use (TOCTOU)9//!10//! Many filesystem operations are subject to a race condition known as "Time of Check to Time of Use"11//! (TOCTOU). This occurs when a program checks a condition (like file existence or permissions)12//! and then uses the result of that check to make a decision, but the condition may have changed13//! between the check and the use.14//!15//! For example, checking if a file exists and then creating it if it doesn't is vulnerable to16//! TOCTOU - another process could create the file between your check and creation attempt.17//!18//! Another example is with symbolic links: when removing a directory, if another process replaces19//! the directory with a symbolic link between the check and the removal operation, the removal20//! might affect the wrong location. This is why operations like [`remove_dir_all`] need to use21//! atomic operations to prevent such race conditions.22//!23//! To avoid TOCTOU issues:24//! - Be aware that metadata operations (like [`metadata`] or [`symlink_metadata`]) may be affected by25//! changes made by other processes.26//! - Use atomic operations when possible (like [`File::create_new`] instead of checking existence then creating).27//! - Keep file open for the duration of operations.2829#![stable(feature = "rust1", since = "1.0.0")]30#![deny(unsafe_op_in_unsafe_fn)]3132#[cfg(all(33    test,34    not(any(35        target_os = "emscripten",36        target_os = "wasi",37        target_env = "sgx",38        target_os = "xous",39        target_os = "trusty",40    ))41))]42mod tests;4344use crate::ffi::OsString;45use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write};46use crate::path::{Path, PathBuf};47use crate::sys::{AsInner, AsInnerMut, FromInner, IntoInner, fs as fs_imp};48use crate::time::SystemTime;49use crate::{error, fmt};5051/// An object providing access to an open file on the filesystem.52///53/// An instance of a `File` can be read and/or written depending on what options54/// it was opened with. Files also implement [`Seek`] to alter the logical cursor55/// that the file contains internally.56///57/// Files are automatically closed when they go out of scope.  Errors detected58/// on closing are ignored by the implementation of `Drop`.  Use the method59/// [`sync_all`] if these errors must be manually handled.60///61/// `File` does not buffer reads and writes. For efficiency, consider wrapping the62/// file in a [`BufReader`] or [`BufWriter`] when performing many small [`read`]63/// or [`write`] calls, unless unbuffered reads and writes are required.64///65/// # Examples66///67/// Creates a new file and write bytes to it (you can also use [`write`]):68///69/// ```no_run70/// use std::fs::File;71/// use std::io::prelude::*;72///73/// fn main() -> std::io::Result<()> {74///     let mut file = File::create("foo.txt")?;75///     file.write_all(b"Hello, world!")?;76///     Ok(())77/// }78/// ```79///80/// Reads the contents of a file into a [`String`] (you can also use [`read`]):81///82/// ```no_run83/// use std::fs::File;84/// use std::io::prelude::*;85///86/// fn main() -> std::io::Result<()> {87///     let mut file = File::open("foo.txt")?;88///     let mut contents = String::new();89///     file.read_to_string(&mut contents)?;90///     assert_eq!(contents, "Hello, world!");91///     Ok(())92/// }93/// ```94///95/// Using a buffered [`Read`]er:96///97/// ```no_run98/// use std::fs::File;99/// use std::io::BufReader;100/// use std::io::prelude::*;101///102/// fn main() -> std::io::Result<()> {103///     let file = File::open("foo.txt")?;104///     let mut buf_reader = BufReader::new(file);105///     let mut contents = String::new();106///     buf_reader.read_to_string(&mut contents)?;107///     assert_eq!(contents, "Hello, world!");108///     Ok(())109/// }110/// ```111///112/// Note that, although read and write methods require a `&mut File`, because113/// of the interfaces for [`Read`] and [`Write`], the holder of a `&File` can114/// still modify the file, either through methods that take `&File` or by115/// retrieving the underlying OS object and modifying the file that way.116/// Additionally, many operating systems allow concurrent modification of files117/// by different processes. Avoid assuming that holding a `&File` means that the118/// file will not change.119///120/// # Platform-specific behavior121///122/// On Windows, the implementation of [`Read`] and [`Write`] traits for `File`123/// perform synchronous I/O operations. Therefore the underlying file must not124/// have been opened for asynchronous I/O (e.g. by using `FILE_FLAG_OVERLAPPED`).125///126/// [`BufReader`]: io::BufReader127/// [`BufWriter`]: io::BufWriter128/// [`sync_all`]: File::sync_all129/// [`write`]: File::write130/// [`read`]: File::read131#[stable(feature = "rust1", since = "1.0.0")]132#[cfg_attr(not(test), rustc_diagnostic_item = "File")]133#[diagnostic::on_move(note = "you can use `File::try_clone` to duplicate a `File` instance")]134pub struct File {135    inner: fs_imp::File,136}137138/// An enumeration of possible errors which can occur while trying to acquire a lock139/// from the [`try_lock`] method and [`try_lock_shared`] method on a [`File`].140///141/// [`try_lock`]: File::try_lock142/// [`try_lock_shared`]: File::try_lock_shared143#[stable(feature = "file_lock", since = "1.89.0")]144pub enum TryLockError {145    /// The lock could not be acquired due to an I/O error on the file. The standard library will146    /// not return an [`ErrorKind::WouldBlock`] error inside [`TryLockError::Error`]147    ///148    /// [`ErrorKind::WouldBlock`]: io::ErrorKind::WouldBlock149    Error(io::Error),150    /// The lock could not be acquired at this time because it is held by another handle/process.151    WouldBlock,152}153154/// An object providing access to a directory on the filesystem.155///156/// Directories are automatically closed when they go out of scope.  Errors detected157/// on closing are ignored by the implementation of `Drop`.158///159/// # Platform-specific behavior160///161/// On supported systems (including Windows and some UNIX-based OSes), this function acquires a162/// handle/file descriptor for the directory. This allows functions like [`Dir::open_file`] to163/// avoid [TOCTOU] errors when the directory itself is being moved.164///165/// On other systems, it stores an absolute path (see [`canonicalize()`]). In the latter case, no166/// [TOCTOU] guarantees are made.167///168/// # Examples169///170/// Opens a directory and then a file inside it.171///172/// ```no_run173/// #![feature(dirfd)]174/// use std::{fs::Dir, io};175///176/// fn main() -> std::io::Result<()> {177///     let dir = Dir::open("foo")?;178///     let mut file = dir.open_file("bar.txt")?;179///     let contents = io::read_to_string(file)?;180///     assert_eq!(contents, "Hello, world!");181///     Ok(())182/// }183/// ```184///185/// [TOCTOU]: self#time-of-check-to-time-of-use-toctou186#[unstable(feature = "dirfd", issue = "120426")]187pub struct Dir {188    inner: fs_imp::Dir,189}190191/// Metadata information about a file.192///193/// This structure is returned from the [`metadata`] or194/// [`symlink_metadata`] function or method and represents known195/// metadata about a file such as its permissions, size, modification196/// times, etc.197#[stable(feature = "rust1", since = "1.0.0")]198#[derive(Clone)]199pub struct Metadata(fs_imp::FileAttr);200201/// Iterator over the entries in a directory.202///203/// This iterator is returned from the [`read_dir`] function of this module and204/// will yield instances of <code>[io::Result]<[DirEntry]></code>. Through a [`DirEntry`]205/// information like the entry's path and possibly other metadata can be206/// learned.207///208/// The order in which this iterator returns entries is platform and filesystem209/// dependent.210///211/// # Errors212/// This [`io::Result`] will be an [`Err`] if an error occurred while fetching213/// the next entry from the OS.214#[stable(feature = "rust1", since = "1.0.0")]215#[derive(Debug)]216pub struct ReadDir(fs_imp::ReadDir);217218/// Entries returned by the [`ReadDir`] iterator.219///220/// An instance of `DirEntry` represents an entry inside of a directory on the221/// filesystem. Each entry can be inspected via methods to learn about the full222/// path or possibly other metadata through per-platform extension traits.223///224/// # Platform-specific behavior225///226/// On Unix, the `DirEntry` struct contains an internal reference to the open227/// directory. Holding `DirEntry` objects will consume a file handle even228/// after the `ReadDir` iterator is dropped.229///230/// Note that this [may change in the future][changes].231///232/// [changes]: io#platform-specific-behavior233#[stable(feature = "rust1", since = "1.0.0")]234pub struct DirEntry(fs_imp::DirEntry);235236/// Options and flags which can be used to configure how a file is opened.237///238/// This builder exposes the ability to configure how a [`File`] is opened and239/// what operations are permitted on the open file. The [`File::open`] and240/// [`File::create`] methods are aliases for commonly used options using this241/// builder.242///243/// Generally speaking, when using `OpenOptions`, you'll first call244/// [`OpenOptions::new`], then chain calls to methods to set each option, then245/// call [`OpenOptions::open`], passing the path of the file you're trying to246/// open. This will give you a [`io::Result`] with a [`File`] inside that you247/// can further operate on.248///249/// # Examples250///251/// Opening a file to read:252///253/// ```no_run254/// use std::fs::OpenOptions;255///256/// let file = OpenOptions::new().read(true).open("foo.txt");257/// ```258///259/// Opening a file for both reading and writing, as well as creating it if it260/// doesn't exist:261///262/// ```no_run263/// use std::fs::OpenOptions;264///265/// let file = OpenOptions::new()266///             .read(true)267///             .write(true)268///             .create(true)269///             .open("foo.txt");270/// ```271#[derive(Clone, Debug)]272#[stable(feature = "rust1", since = "1.0.0")]273#[cfg_attr(not(test), rustc_diagnostic_item = "FsOpenOptions")]274pub struct OpenOptions(fs_imp::OpenOptions);275276/// Representation of the various timestamps on a file.277#[derive(Copy, Clone, Debug, Default)]278#[stable(feature = "file_set_times", since = "1.75.0")]279#[must_use = "must be applied to a file via `File::set_times` to have any effect"]280pub struct FileTimes(fs_imp::FileTimes);281282/// Representation of the various permissions on a file.283///284/// This module only currently provides one bit of information,285/// [`Permissions::readonly`], which is exposed on all currently supported286/// platforms. Unix-specific functionality, such as mode bits, is available287/// through the [`PermissionsExt`] trait.288///289/// [`PermissionsExt`]: crate::os::unix::fs::PermissionsExt290#[derive(Clone, PartialEq, Eq, Debug)]291#[stable(feature = "rust1", since = "1.0.0")]292#[cfg_attr(not(test), rustc_diagnostic_item = "FsPermissions")]293pub struct Permissions(fs_imp::FilePermissions);294295/// A structure representing a type of file with accessors for each file type.296/// It is returned by [`Metadata::file_type`] method.297#[stable(feature = "file_type", since = "1.1.0")]298#[derive(Copy, Clone, PartialEq, Eq, Hash)]299#[cfg_attr(not(test), rustc_diagnostic_item = "FileType")]300pub struct FileType(fs_imp::FileType);301302/// A builder used to create directories in various manners.303///304/// This builder also supports platform-specific options.305#[stable(feature = "dir_builder", since = "1.6.0")]306#[cfg_attr(not(test), rustc_diagnostic_item = "DirBuilder")]307#[derive(Debug)]308pub struct DirBuilder {309    inner: fs_imp::DirBuilder,310    recursive: bool,311}312313/// Reads the entire contents of a file into a bytes vector.314///315/// This is a convenience function for using [`File::open`] and [`read_to_end`]316/// with fewer imports and without an intermediate variable.317///318/// [`read_to_end`]: Read::read_to_end319///320/// # Errors321///322/// This function will return an error if `path` does not already exist.323/// Other errors may also be returned according to [`OpenOptions::open`].324///325/// While reading from the file, this function handles [`io::ErrorKind::Interrupted`]326/// with automatic retries. See [io::Read] documentation for details.327///328/// # Examples329///330/// ```no_run331/// use std::fs;332///333/// fn main() -> Result<(), Box<dyn std::error::Error + 'static>> {334///     let data: Vec<u8> = fs::read("image.jpg")?;335///     assert_eq!(data[0..3], [0xFF, 0xD8, 0xFF]);336///     Ok(())337/// }338/// ```339#[stable(feature = "fs_read_write_bytes", since = "1.26.0")]340pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {341    fn inner(path: &Path) -> io::Result<Vec<u8>> {342        let mut file = File::open(path)?;343        let size = file.metadata().map(|m| usize::try_from(m.len()).unwrap_or(usize::MAX)).ok();344        let mut bytes = Vec::try_with_capacity(size.unwrap_or(0))?;345        io::default_read_to_end(&mut file, &mut bytes, size)?;346        Ok(bytes)347    }348    inner(path.as_ref())349}350351/// Reads the entire contents of a file into a string.352///353/// This is a convenience function for using [`File::open`] and [`read_to_string`]354/// with fewer imports and without an intermediate variable.355///356/// [`read_to_string`]: Read::read_to_string357///358/// # Errors359///360/// This function will return an error if `path` does not already exist.361/// Other errors may also be returned according to [`OpenOptions::open`].362///363/// If the contents of the file are not valid UTF-8, then an error will also be364/// returned.365///366/// While reading from the file, this function handles [`io::ErrorKind::Interrupted`]367/// with automatic retries. See [io::Read] documentation for details.368///369/// # Examples370///371/// ```no_run372/// use std::fs;373/// use std::error::Error;374///375/// fn main() -> Result<(), Box<dyn Error>> {376///     let message: String = fs::read_to_string("message.txt")?;377///     println!("{}", message);378///     Ok(())379/// }380/// ```381#[stable(feature = "fs_read_write", since = "1.26.0")]382pub fn read_to_string<P: AsRef<Path>>(path: P) -> io::Result<String> {383    fn inner(path: &Path) -> io::Result<String> {384        let mut file = File::open(path)?;385        let size = file.metadata().map(|m| usize::try_from(m.len()).unwrap_or(usize::MAX)).ok();386        let mut string = String::new();387        string.try_reserve_exact(size.unwrap_or(0))?;388        io::default_read_to_string(&mut file, &mut string, size)?;389        Ok(string)390    }391    inner(path.as_ref())392}393394/// Writes a slice as the entire contents of a file.395///396/// This function will create a file if it does not exist,397/// and will entirely replace its contents if it does.398///399/// Depending on the platform, this function may fail if the400/// full directory path does not exist.401///402/// This is a convenience function for using [`File::create`] and [`write_all`]403/// with fewer imports.404///405/// [`write_all`]: Write::write_all406///407/// # Examples408///409/// ```no_run410/// use std::fs;411///412/// fn main() -> std::io::Result<()> {413///     fs::write("foo.txt", b"Lorem ipsum")?;414///     fs::write("bar.txt", "dolor sit")?;415///     Ok(())416/// }417/// ```418#[stable(feature = "fs_read_write_bytes", since = "1.26.0")]419pub fn write<P: AsRef<Path>, C: AsRef<[u8]>>(path: P, contents: C) -> io::Result<()> {420    fn inner(path: &Path, contents: &[u8]) -> io::Result<()> {421        File::create(path)?.write_all(contents)422    }423    inner(path.as_ref(), contents.as_ref())424}425426/// Changes the timestamps of the file or directory at the specified path.427///428/// This function will attempt to set the access and modification times429/// to the times specified. If the path refers to a symbolic link, this function430/// will follow the link and change the timestamps of the target file.431///432/// # Platform-specific behavior433///434/// This function currently corresponds to the `utimensat` function on Unix platforms, the435/// `setattrlist` function on Apple platforms, and the `SetFileTime` function on Windows.436///437/// # Errors438///439/// This function will return an error if the user lacks permission to change timestamps on the440/// target file or symlink. It may also return an error if the OS does not support it.441///442/// # Examples443///444/// ```no_run445/// #![feature(fs_set_times)]446/// use std::fs::{self, FileTimes};447/// use std::time::SystemTime;448///449/// fn main() -> std::io::Result<()> {450///     let now = SystemTime::now();451///     let times = FileTimes::new()452///         .set_accessed(now)453///         .set_modified(now);454///     fs::set_times("foo.txt", times)?;455///     Ok(())456/// }457/// ```458#[unstable(feature = "fs_set_times", issue = "147455")]459#[doc(alias = "utimens")]460#[doc(alias = "utimes")]461#[doc(alias = "utime")]462pub fn set_times<P: AsRef<Path>>(path: P, times: FileTimes) -> io::Result<()> {463    fs_imp::set_times(path.as_ref(), times.0)464}465466/// Changes the timestamps of the file or symlink at the specified path.467///468/// This function will attempt to set the access and modification times469/// to the times specified. Differ from `set_times`, if the path refers to a symbolic link,470/// this function will change the timestamps of the symlink itself, not the target file.471///472/// # Platform-specific behavior473///474/// This function currently corresponds to the `utimensat` function with `AT_SYMLINK_NOFOLLOW` on475/// Unix platforms, the `setattrlist` function with `FSOPT_NOFOLLOW` on Apple platforms, and the476/// `SetFileTime` function on Windows.477///478/// # Errors479///480/// This function will return an error if the user lacks permission to change timestamps on the481/// target file or symlink. It may also return an error if the OS does not support it.482///483/// # Examples484///485/// ```no_run486/// #![feature(fs_set_times)]487/// use std::fs::{self, FileTimes};488/// use std::time::SystemTime;489///490/// fn main() -> std::io::Result<()> {491///     let now = SystemTime::now();492///     let times = FileTimes::new()493///         .set_accessed(now)494///         .set_modified(now);495///     fs::set_times_nofollow("symlink.txt", times)?;496///     Ok(())497/// }498/// ```499#[unstable(feature = "fs_set_times", issue = "147455")]500#[doc(alias = "utimensat")]501#[doc(alias = "lutimens")]502#[doc(alias = "lutimes")]503pub fn set_times_nofollow<P: AsRef<Path>>(path: P, times: FileTimes) -> io::Result<()> {504    fs_imp::set_times_nofollow(path.as_ref(), times.0)505}506507#[stable(feature = "file_lock", since = "1.89.0")]508impl error::Error for TryLockError {}509510#[stable(feature = "file_lock", since = "1.89.0")]511impl fmt::Debug for TryLockError {512    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {513        match self {514            TryLockError::Error(err) => err.fmt(f),515            TryLockError::WouldBlock => "WouldBlock".fmt(f),516        }517    }518}519520#[stable(feature = "file_lock", since = "1.89.0")]521impl fmt::Display for TryLockError {522    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {523        match self {524            TryLockError::Error(_) => "lock acquisition failed due to I/O error",525            TryLockError::WouldBlock => "lock acquisition failed because the operation would block",526        }527        .fmt(f)528    }529}530531#[stable(feature = "file_lock", since = "1.89.0")]532impl From<TryLockError> for io::Error {533    fn from(err: TryLockError) -> io::Error {534        match err {535            TryLockError::Error(err) => err,536            TryLockError::WouldBlock => io::ErrorKind::WouldBlock.into(),537        }538    }539}540541impl File {542    /// Attempts to open a file in read-only mode.543    ///544    /// See the [`OpenOptions::open`] method for more details.545    ///546    /// If you only need to read the entire file contents,547    /// consider [`std::fs::read()`][self::read] or548    /// [`std::fs::read_to_string()`][self::read_to_string] instead.549    ///550    /// # Errors551    ///552    /// This function will return an error if `path` does not already exist.553    /// Other errors may also be returned according to [`OpenOptions::open`].554    ///555    /// # Examples556    ///557    /// ```no_run558    /// use std::fs::File;559    /// use std::io::Read;560    ///561    /// fn main() -> std::io::Result<()> {562    ///     let mut f = File::open("foo.txt")?;563    ///     let mut data = vec![];564    ///     f.read_to_end(&mut data)?;565    ///     Ok(())566    /// }567    /// ```568    #[stable(feature = "rust1", since = "1.0.0")]569    pub fn open<P: AsRef<Path>>(path: P) -> io::Result<File> {570        OpenOptions::new().read(true).open(path.as_ref())571    }572573    /// Attempts to open a file in read-only mode with buffering.574    ///575    /// See the [`OpenOptions::open`] method, the [`BufReader`][io::BufReader] type,576    /// and the [`BufRead`][io::BufRead] trait for more details.577    ///578    /// If you only need to read the entire file contents,579    /// consider [`std::fs::read()`][self::read] or580    /// [`std::fs::read_to_string()`][self::read_to_string] instead.581    ///582    /// # Errors583    ///584    /// This function will return an error if `path` does not already exist,585    /// or if memory allocation fails for the new buffer.586    /// Other errors may also be returned according to [`OpenOptions::open`].587    ///588    /// # Examples589    ///590    /// ```no_run591    /// #![feature(file_buffered)]592    /// use std::fs::File;593    /// use std::io::BufRead;594    ///595    /// fn main() -> std::io::Result<()> {596    ///     let mut f = File::open_buffered("foo.txt")?;597    ///     assert!(f.capacity() > 0);598    ///     for (line, i) in f.lines().zip(1..) {599    ///         println!("{i:6}: {}", line?);600    ///     }601    ///     Ok(())602    /// }603    /// ```604    #[unstable(feature = "file_buffered", issue = "130804")]605    pub fn open_buffered<P: AsRef<Path>>(path: P) -> io::Result<io::BufReader<File>> {606        // Allocate the buffer *first* so we don't affect the filesystem otherwise.607        let buffer = io::BufReader::<Self>::try_new_buffer()?;608        let file = File::open(path)?;609        Ok(io::BufReader::with_buffer(file, buffer))610    }611612    /// Opens a file in write-only mode.613    ///614    /// This function will create a file if it does not exist,615    /// and will truncate it if it does.616    ///617    /// Depending on the platform, this function may fail if the618    /// full directory path does not exist.619    /// See the [`OpenOptions::open`] function for more details.620    ///621    /// See also [`std::fs::write()`][self::write] for a simple function to622    /// create a file with some given data.623    ///624    /// # Examples625    ///626    /// ```no_run627    /// use std::fs::File;628    /// use std::io::Write;629    ///630    /// fn main() -> std::io::Result<()> {631    ///     let mut f = File::create("foo.txt")?;632    ///     f.write_all(&1234_u32.to_be_bytes())?;633    ///     Ok(())634    /// }635    /// ```636    #[stable(feature = "rust1", since = "1.0.0")]637    pub fn create<P: AsRef<Path>>(path: P) -> io::Result<File> {638        OpenOptions::new().write(true).create(true).truncate(true).open(path.as_ref())639    }640641    /// Opens a file in write-only mode with buffering.642    ///643    /// This function will create a file if it does not exist,644    /// and will truncate it if it does.645    ///646    /// Depending on the platform, this function may fail if the647    /// full directory path does not exist.648    ///649    /// See the [`OpenOptions::open`] method and the650    /// [`BufWriter`][io::BufWriter] type for more details.651    ///652    /// See also [`std::fs::write()`][self::write] for a simple function to653    /// create a file with some given data.654    ///655    /// # Examples656    ///657    /// ```no_run658    /// #![feature(file_buffered)]659    /// use std::fs::File;660    /// use std::io::Write;661    ///662    /// fn main() -> std::io::Result<()> {663    ///     let mut f = File::create_buffered("foo.txt")?;664    ///     assert!(f.capacity() > 0);665    ///     for i in 0..100 {666    ///         writeln!(&mut f, "{i}")?;667    ///     }668    ///     f.flush()?;669    ///     Ok(())670    /// }671    /// ```672    #[unstable(feature = "file_buffered", issue = "130804")]673    pub fn create_buffered<P: AsRef<Path>>(path: P) -> io::Result<io::BufWriter<File>> {674        // Allocate the buffer *first* so we don't affect the filesystem otherwise.675        let buffer = io::BufWriter::<Self>::try_new_buffer()?;676        let file = File::create(path)?;677        Ok(io::BufWriter::with_buffer(file, buffer))678    }679680    /// Creates a new file in read-write mode; error if the file exists.681    ///682    /// This function will create a file if it does not exist, or return an error if it does. This683    /// way, if the call succeeds, the file returned is guaranteed to be new.684    /// If a file exists at the target location, creating a new file will fail with [`AlreadyExists`]685    /// or another error based on the situation. See [`OpenOptions::open`] for a686    /// non-exhaustive list of likely errors.687    ///688    /// This option is useful because it is atomic. Otherwise between checking whether a file689    /// exists and creating a new one, the file may have been created by another process (a [TOCTOU]690    /// race condition / attack).691    ///692    /// This can also be written using693    /// `File::options().read(true).write(true).create_new(true).open(...)`.694    ///695    /// [`AlreadyExists`]: crate::io::ErrorKind::AlreadyExists696    /// [TOCTOU]: self#time-of-check-to-time-of-use-toctou697    ///698    /// # Examples699    ///700    /// ```no_run701    /// use std::fs::File;702    /// use std::io::Write;703    ///704    /// fn main() -> std::io::Result<()> {705    ///     let mut f = File::create_new("foo.txt")?;706    ///     f.write_all("Hello, world!".as_bytes())?;707    ///     Ok(())708    /// }709    /// ```710    #[stable(feature = "file_create_new", since = "1.77.0")]711    pub fn create_new<P: AsRef<Path>>(path: P) -> io::Result<File> {712        OpenOptions::new().read(true).write(true).create_new(true).open(path.as_ref())713    }714715    /// Returns a new OpenOptions object.716    ///717    /// This function returns a new OpenOptions object that you can use to718    /// open or create a file with specific options if `open()` or `create()`719    /// are not appropriate.720    ///721    /// It is equivalent to `OpenOptions::new()`, but allows you to write more722    /// readable code. Instead of723    /// `OpenOptions::new().append(true).open("example.log")`,724    /// you can write `File::options().append(true).open("example.log")`. This725    /// also avoids the need to import `OpenOptions`.726    ///727    /// See the [`OpenOptions::new`] function for more details.728    ///729    /// # Examples730    ///731    /// ```no_run732    /// use std::fs::File;733    /// use std::io::Write;734    ///735    /// fn main() -> std::io::Result<()> {736    ///     let mut f = File::options().append(true).open("example.log")?;737    ///     writeln!(&mut f, "new line")?;738    ///     Ok(())739    /// }740    /// ```741    #[must_use]742    #[stable(feature = "with_options", since = "1.58.0")]743    #[cfg_attr(not(test), rustc_diagnostic_item = "file_options")]744    pub fn options() -> OpenOptions {745        OpenOptions::new()746    }747748    /// Attempts to sync all OS-internal file content and metadata to disk.749    ///750    /// This function will attempt to ensure that all in-memory data reaches the751    /// filesystem before returning.752    ///753    /// This can be used to handle errors that would otherwise only be caught754    /// when the `File` is closed, as dropping a `File` will ignore all errors.755    /// Note, however, that `sync_all` is generally more expensive than closing756    /// a file by dropping it, because the latter is not required to block until757    /// the data has been written to the filesystem.758    ///759    /// If synchronizing the metadata is not required, use [`sync_data`] instead.760    ///761    /// [`sync_data`]: File::sync_data762    ///763    /// # Examples764    ///765    /// ```no_run766    /// use std::fs::File;767    /// use std::io::prelude::*;768    ///769    /// fn main() -> std::io::Result<()> {770    ///     let mut f = File::create("foo.txt")?;771    ///     f.write_all(b"Hello, world!")?;772    ///773    ///     f.sync_all()?;774    ///     Ok(())775    /// }776    /// ```777    #[stable(feature = "rust1", since = "1.0.0")]778    #[doc(alias = "fsync")]779    pub fn sync_all(&self) -> io::Result<()> {780        self.inner.fsync()781    }782783    /// This function is similar to [`sync_all`], except that it might not784    /// synchronize file metadata to the filesystem.785    ///786    /// This is intended for use cases that must synchronize content, but don't787    /// need the metadata on disk. The goal of this method is to reduce disk788    /// operations.789    ///790    /// Note that some platforms may simply implement this in terms of791    /// [`sync_all`].792    ///793    /// [`sync_all`]: File::sync_all794    ///795    /// # Examples796    ///797    /// ```no_run798    /// use std::fs::File;799    /// use std::io::prelude::*;800    ///801    /// fn main() -> std::io::Result<()> {802    ///     let mut f = File::create("foo.txt")?;803    ///     f.write_all(b"Hello, world!")?;804    ///805    ///     f.sync_data()?;806    ///     Ok(())807    /// }808    /// ```809    #[stable(feature = "rust1", since = "1.0.0")]810    #[doc(alias = "fdatasync")]811    pub fn sync_data(&self) -> io::Result<()> {812        self.inner.datasync()813    }814815    /// Acquire an exclusive lock on the file. Blocks until the lock can be acquired.816    ///817    /// This acquires an exclusive lock. No *other* file handle to this file, in this or any other818    /// process, may acquire another lock.819    /// If this file handle/descriptor, or a clone of it, already holds a lock, the exact behavior820    /// is unspecified and platform dependent, including the possibility that it will deadlock.821    /// However, if this method returns, then an exclusive lock is held.822    ///823    /// This lock may be advisory or mandatory. This lock is meant to interact with [`lock`],824    /// [`try_lock`], [`lock_shared`], [`try_lock_shared`], and [`unlock`]. Its interactions with825    /// other methods, such as [`read`] and [`write`] are platform specific, and it may or may not826    /// cause non-lockholders to block.827    ///828    /// If the file is not open for writing, it is unspecified whether this function returns an error.829    ///830    /// The lock will be released when this file (along with any other file descriptors/handles831    /// duplicated or inherited from it) is closed, or if the [`unlock`] method is called.832    ///833    /// # Platform-specific behavior834    ///835    /// This function currently corresponds to the `flock` function on Unix with the `LOCK_EX` flag,836    /// and the `LockFileEx` function on Windows with the `LOCKFILE_EXCLUSIVE_LOCK` flag. Note that,837    /// this [may change in the future][changes].838    ///839    /// On Windows, locking a file will fail if the file is opened only for append. To lock a file,840    /// open it with one of `.read(true)`, `.read(true).append(true)`, or `.write(true)`.841    ///842    /// [changes]: io#platform-specific-behavior843    ///844    /// [`lock`]: File::lock845    /// [`lock_shared`]: File::lock_shared846    /// [`try_lock`]: File::try_lock847    /// [`try_lock_shared`]: File::try_lock_shared848    /// [`unlock`]: File::unlock849    /// [`read`]: Read::read850    /// [`write`]: Write::write851    ///852    /// # Examples853    ///854    /// ```no_run855    /// use std::fs::File;856    ///857    /// fn main() -> std::io::Result<()> {858    ///     let f = File::create("foo.txt")?;859    ///     f.lock()?;860    ///     Ok(())861    /// }862    /// ```863    #[stable(feature = "file_lock", since = "1.89.0")]864    pub fn lock(&self) -> io::Result<()> {865        self.inner.lock()866    }867868    /// Acquire a shared (non-exclusive) lock on the file. Blocks until the lock can be acquired.869    ///870    /// This acquires a shared lock. More than one file handle to this file, in this or any other871    /// process, may hold a shared lock, but no *other* file handle may hold an exclusive lock at872    /// the same time.873    /// If this file handle/descriptor, or a clone of it, already holds a lock, the exact874    /// behavior is unspecified and platform dependent, including the possibility that it will875    /// deadlock. However, if this method returns, then a shared lock is held.876    ///877    /// This lock may be advisory or mandatory. This lock is meant to interact with [`lock`],878    /// [`try_lock`], [`lock_shared`], [`try_lock_shared`], and [`unlock`]. Its interactions with879    /// other methods, such as [`read`] and [`write`] are platform specific, and it may or may not880    /// cause non-lockholders to block.881    ///882    /// The lock will be released when this file (along with any other file descriptors/handles883    /// duplicated or inherited from it) is closed, or if the [`unlock`] method is called.884    ///885    /// # Platform-specific behavior886    ///887    /// This function currently corresponds to the `flock` function on Unix with the `LOCK_SH` flag,888    /// and the `LockFileEx` function on Windows. Note that, this889    /// [may change in the future][changes].890    ///891    /// On Windows, locking a file will fail if the file is opened only for append. To lock a file,892    /// open it with one of `.read(true)`, `.read(true).append(true)`, or `.write(true)`.893    ///894    /// [changes]: io#platform-specific-behavior895    ///896    /// [`lock`]: File::lock897    /// [`lock_shared`]: File::lock_shared898    /// [`try_lock`]: File::try_lock899    /// [`try_lock_shared`]: File::try_lock_shared900    /// [`unlock`]: File::unlock901    /// [`read`]: Read::read902    /// [`write`]: Write::write903    ///904    /// # Examples905    ///906    /// ```no_run907    /// use std::fs::File;908    ///909    /// fn main() -> std::io::Result<()> {910    ///     let f = File::open("foo.txt")?;911    ///     f.lock_shared()?;912    ///     Ok(())913    /// }914    /// ```915    #[stable(feature = "file_lock", since = "1.89.0")]916    pub fn lock_shared(&self) -> io::Result<()> {917        self.inner.lock_shared()918    }919920    /// Try to acquire an exclusive lock on the file.921    ///922    /// Returns `Err(TryLockError::WouldBlock)` if a different lock is already held on this file923    /// (via another handle/descriptor).924    ///925    /// This acquires an exclusive lock; no other file handle to this file, in this or any other926    /// process, may acquire another lock.927    ///928    /// This lock may be advisory or mandatory. This lock is meant to interact with [`lock`],929    /// [`try_lock`], [`lock_shared`], [`try_lock_shared`], and [`unlock`]. Its interactions with930    /// other methods, such as [`read`] and [`write`] are platform specific, and it may or may not931    /// cause non-lockholders to block.932    ///933    /// If this file handle/descriptor, or a clone of it, already holds a lock, the exact behavior934    /// is unspecified and platform dependent, including the possibility that it will deadlock.935    /// However, if this method returns `Ok(())`, then it has acquired an exclusive lock.936    ///937    /// If the file is not open for writing, it is unspecified whether this function returns an error.938    ///939    /// The lock will be released when this file (along with any other file descriptors/handles940    /// duplicated or inherited from it) is closed, or if the [`unlock`] method is called.941    ///942    /// # Platform-specific behavior943    ///944    /// This function currently corresponds to the `flock` function on Unix with the `LOCK_EX` and945    /// `LOCK_NB` flags, and the `LockFileEx` function on Windows with the `LOCKFILE_EXCLUSIVE_LOCK`946    /// and `LOCKFILE_FAIL_IMMEDIATELY` flags. Note that, this947    /// [may change in the future][changes].948    ///949    /// On Windows, locking a file will fail if the file is opened only for append. To lock a file,950    /// open it with one of `.read(true)`, `.read(true).append(true)`, or `.write(true)`.951    ///952    /// [changes]: io#platform-specific-behavior953    ///954    /// [`lock`]: File::lock955    /// [`lock_shared`]: File::lock_shared956    /// [`try_lock`]: File::try_lock957    /// [`try_lock_shared`]: File::try_lock_shared958    /// [`unlock`]: File::unlock959    /// [`read`]: Read::read960    /// [`write`]: Write::write961    ///962    /// # Examples963    ///964    /// ```no_run965    /// use std::fs::{File, TryLockError};966    ///967    /// fn main() -> std::io::Result<()> {968    ///     let f = File::create("foo.txt")?;969    ///     // Explicit handling of the WouldBlock error970    ///     match f.try_lock() {971    ///         Ok(_) => (),972    ///         Err(TryLockError::WouldBlock) => (), // Lock not acquired973    ///         Err(TryLockError::Error(err)) => return Err(err),974    ///     }975    ///     // Alternately, propagate the error as an io::Error976    ///     f.try_lock()?;977    ///     Ok(())978    /// }979    /// ```980    #[stable(feature = "file_lock", since = "1.89.0")]981    pub fn try_lock(&self) -> Result<(), TryLockError> {982        self.inner.try_lock()983    }984985    /// Try to acquire a shared (non-exclusive) lock on the file.986    ///987    /// Returns `Err(TryLockError::WouldBlock)` if a different lock is already held on this file988    /// (via another handle/descriptor).989    ///990    /// This acquires a shared lock; more than one file handle, in this or any other process, may991    /// hold a shared lock, but none may hold an exclusive lock at the same time.992    ///993    /// This lock may be advisory or mandatory. This lock is meant to interact with [`lock`],994    /// [`try_lock`], [`lock_shared`], [`try_lock_shared`], and [`unlock`]. Its interactions with995    /// other methods, such as [`read`] and [`write`] are platform specific, and it may or may not996    /// cause non-lockholders to block.997    ///998    /// If this file handle, or a clone of it, already holds a lock, the exact behavior is999    /// unspecified and platform dependent, including the possibility that it will deadlock.1000    /// However, if this method returns `Ok(())`, then it has acquired a shared lock.1001    ///1002    /// The lock will be released when this file (along with any other file descriptors/handles1003    /// duplicated or inherited from it) is closed, or if the [`unlock`] method is called.1004    ///1005    /// # Platform-specific behavior1006    ///1007    /// This function currently corresponds to the `flock` function on Unix with the `LOCK_SH` and1008    /// `LOCK_NB` flags, and the `LockFileEx` function on Windows with the1009    /// `LOCKFILE_FAIL_IMMEDIATELY` flag. Note that, this1010    /// [may change in the future][changes].1011    ///1012    /// On Windows, locking a file will fail if the file is opened only for append. To lock a file,1013    /// open it with one of `.read(true)`, `.read(true).append(true)`, or `.write(true)`.1014    ///1015    /// [changes]: io#platform-specific-behavior1016    ///1017    /// [`lock`]: File::lock1018    /// [`lock_shared`]: File::lock_shared1019    /// [`try_lock`]: File::try_lock1020    /// [`try_lock_shared`]: File::try_lock_shared1021    /// [`unlock`]: File::unlock1022    /// [`read`]: Read::read1023    /// [`write`]: Write::write1024    ///1025    /// # Examples1026    ///1027    /// ```no_run1028    /// use std::fs::{File, TryLockError};1029    ///1030    /// fn main() -> std::io::Result<()> {1031    ///     let f = File::open("foo.txt")?;1032    ///     // Explicit handling of the WouldBlock error1033    ///     match f.try_lock_shared() {1034    ///         Ok(_) => (),1035    ///         Err(TryLockError::WouldBlock) => (), // Lock not acquired1036    ///         Err(TryLockError::Error(err)) => return Err(err),1037    ///     }1038    ///     // Alternately, propagate the error as an io::Error1039    ///     f.try_lock_shared()?;1040    ///1041    ///     Ok(())1042    /// }1043    /// ```1044    #[stable(feature = "file_lock", since = "1.89.0")]1045    pub fn try_lock_shared(&self) -> Result<(), TryLockError> {1046        self.inner.try_lock_shared()1047    }10481049    /// Release all locks on the file.1050    ///1051    /// All locks are released when the file (along with any other file descriptors/handles1052    /// duplicated or inherited from it) is closed. This method allows releasing locks without1053    /// closing the file.1054    ///1055    /// If no lock is currently held via this file descriptor/handle, this method may return an1056    /// error, or may return successfully without taking any action.1057    ///1058    /// # Platform-specific behavior1059    ///1060    /// This function currently corresponds to the `flock` function on Unix with the `LOCK_UN` flag,1061    /// and the `UnlockFile` function on Windows. Note that, this1062    /// [may change in the future][changes].1063    ///1064    /// On Windows, locking a file will fail if the file is opened only for append. To lock a file,1065    /// open it with one of `.read(true)`, `.read(true).append(true)`, or `.write(true)`.1066    ///1067    /// [changes]: io#platform-specific-behavior1068    ///1069    /// # Examples1070    ///1071    /// ```no_run1072    /// use std::fs::File;1073    ///1074    /// fn main() -> std::io::Result<()> {1075    ///     let f = File::open("foo.txt")?;1076    ///     f.lock()?;1077    ///     f.unlock()?;1078    ///     Ok(())1079    /// }1080    /// ```1081    #[stable(feature = "file_lock", since = "1.89.0")]1082    pub fn unlock(&self) -> io::Result<()> {1083        self.inner.unlock()1084    }10851086    /// Truncates or extends the underlying file, updating the size of1087    /// this file to become `size`.1088    ///1089    /// If the `size` is less than the current file's size, then the file will1090    /// be shrunk. If it is greater than the current file's size, then the file1091    /// will be extended to `size` and have all of the intermediate data filled1092    /// in with 0s.1093    ///1094    /// The file's cursor isn't changed. In particular, if the cursor was at the1095    /// end and the file is shrunk using this operation, the cursor will now be1096    /// past the end.1097    ///1098    /// # Errors1099    ///1100    /// This function will return an error if the file is not opened for writing.1101    /// Also, [`std::io::ErrorKind::InvalidInput`](crate::io::ErrorKind::InvalidInput)1102    /// will be returned if the desired length would cause an overflow due to1103    /// the implementation specifics.1104    ///1105    /// # Examples1106    ///1107    /// ```no_run1108    /// use std::fs::File;1109    ///1110    /// fn main() -> std::io::Result<()> {1111    ///     let mut f = File::create("foo.txt")?;1112    ///     f.set_len(10)?;1113    ///     Ok(())1114    /// }1115    /// ```1116    ///1117    /// Note that this method alters the content of the underlying file, even1118    /// though it takes `&self` rather than `&mut self`.1119    #[stable(feature = "rust1", since = "1.0.0")]1120    pub fn set_len(&self, size: u64) -> io::Result<()> {1121        self.inner.truncate(size)1122    }11231124    /// Queries metadata about the underlying file.1125    ///1126    /// # Examples1127    ///1128    /// ```no_run1129    /// use std::fs::File;1130    ///1131    /// fn main() -> std::io::Result<()> {1132    ///     let mut f = File::open("foo.txt")?;1133    ///     let metadata = f.metadata()?;1134    ///     Ok(())1135    /// }1136    /// ```1137    #[stable(feature = "rust1", since = "1.0.0")]1138    pub fn metadata(&self) -> io::Result<Metadata> {1139        self.inner.file_attr().map(Metadata)1140    }11411142    /// Creates a new `File` instance that shares the same underlying file handle1143    /// as the existing `File` instance. Reads, writes, and seeks will affect1144    /// both `File` instances simultaneously.1145    ///1146    /// # Examples1147    ///1148    /// Creates two handles for a file named `foo.txt`:1149    ///1150    /// ```no_run1151    /// use std::fs::File;1152    ///1153    /// fn main() -> std::io::Result<()> {1154    ///     let mut file = File::open("foo.txt")?;1155    ///     let file_copy = file.try_clone()?;1156    ///     Ok(())1157    /// }1158    /// ```1159    ///1160    /// Assuming there’s a file named `foo.txt` with contents `abcdef\n`, create1161    /// two handles, seek one of them, and read the remaining bytes from the1162    /// other handle:1163    ///1164    /// ```no_run1165    /// use std::fs::File;1166    /// use std::io::SeekFrom;1167    /// use std::io::prelude::*;1168    ///1169    /// fn main() -> std::io::Result<()> {1170    ///     let mut file = File::open("foo.txt")?;1171    ///     let mut file_copy = file.try_clone()?;1172    ///1173    ///     file.seek(SeekFrom::Start(3))?;1174    ///1175    ///     let mut contents = vec![];1176    ///     file_copy.read_to_end(&mut contents)?;1177    ///     assert_eq!(contents, b"def\n");1178    ///     Ok(())1179    /// }1180    /// ```1181    #[stable(feature = "file_try_clone", since = "1.9.0")]1182    pub fn try_clone(&self) -> io::Result<File> {1183        Ok(File { inner: self.inner.duplicate()? })1184    }11851186    /// Changes the permissions on the underlying file.1187    ///1188    /// # Platform-specific behavior1189    ///1190    /// This function currently corresponds to the `fchmod` function on Unix and1191    /// the `SetFileInformationByHandle` function on Windows. Note that, this1192    /// [may change in the future][changes].1193    ///1194    /// [changes]: io#platform-specific-behavior1195    ///1196    /// # Errors1197    ///1198    /// This function will return an error if the user lacks permission change1199    /// attributes on the underlying file. It may also return an error in other1200    /// os-specific unspecified cases.1201    ///1202    /// # Examples1203    ///1204    /// ```no_run1205    /// fn main() -> std::io::Result<()> {1206    ///     use std::fs::File;1207    ///1208    ///     let file = File::open("foo.txt")?;1209    ///     let mut perms = file.metadata()?.permissions();1210    ///     perms.set_readonly(true);1211    ///     file.set_permissions(perms)?;1212    ///     Ok(())1213    /// }1214    /// ```1215    ///1216    /// Note that this method alters the permissions of the underlying file,1217    /// even though it takes `&self` rather than `&mut self`.1218    #[doc(alias = "fchmod", alias = "SetFileInformationByHandle")]1219    #[stable(feature = "set_permissions_atomic", since = "1.16.0")]1220    pub fn set_permissions(&self, perm: Permissions) -> io::Result<()> {1221        self.inner.set_permissions(perm.0)1222    }12231224    /// Changes the timestamps of the underlying file.1225    ///1226    /// # Platform-specific behavior1227    ///1228    /// This function currently corresponds to the `futimens` function on Unix (falling back to1229    /// `futimes` on macOS before 10.13) and the `SetFileTime` function on Windows. Note that this1230    /// [may change in the future][changes].1231    ///1232    /// On most platforms, including UNIX and Windows platforms, this function can also change the1233    /// timestamps of a directory. To get a `File` representing a directory in order to call1234    /// `set_times`, open the directory with `File::open` without attempting to obtain write1235    /// permission.1236    ///1237    /// [changes]: io#platform-specific-behavior1238    ///1239    /// # Errors1240    ///1241    /// This function will return an error if the user lacks permission to change timestamps on the1242    /// underlying file. It may also return an error in other os-specific unspecified cases.1243    ///1244    /// This function may return an error if the operating system lacks support to change one or1245    /// more of the timestamps set in the `FileTimes` structure.1246    ///1247    /// # Examples1248    ///1249    /// ```no_run1250    /// fn main() -> std::io::Result<()> {1251    ///     use std::fs::{self, File, FileTimes};1252    ///1253    ///     let src = fs::metadata("src")?;1254    ///     let dest = File::open("dest")?;1255    ///     let times = FileTimes::new()1256    ///         .set_accessed(src.accessed()?)1257    ///         .set_modified(src.modified()?);1258    ///     dest.set_times(times)?;1259    ///     Ok(())1260    /// }1261    /// ```1262    #[stable(feature = "file_set_times", since = "1.75.0")]1263    #[doc(alias = "futimens")]1264    #[doc(alias = "futimes")]1265    #[doc(alias = "SetFileTime")]1266    #[doc(alias = "filetime")]1267    pub fn set_times(&self, times: FileTimes) -> io::Result<()> {1268        self.inner.set_times(times.0)1269    }12701271    /// Changes the modification time of the underlying file.1272    ///1273    /// This is an alias for `set_times(FileTimes::new().set_modified(time))`.1274    #[stable(feature = "file_set_times", since = "1.75.0")]1275    #[inline]1276    pub fn set_modified(&self, time: SystemTime) -> io::Result<()> {1277        self.set_times(FileTimes::new().set_modified(time))1278    }1279}12801281// In addition to the `impl`s here, `File` also has `impl`s for1282// `AsFd`/`From<OwnedFd>`/`Into<OwnedFd>` and1283// `AsRawFd`/`IntoRawFd`/`FromRawFd`, on Unix and WASI, and1284// `AsHandle`/`From<OwnedHandle>`/`Into<OwnedHandle>` and1285// `AsRawHandle`/`IntoRawHandle`/`FromRawHandle` on Windows.12861287impl AsInner<fs_imp::File> for File {1288    #[inline]1289    fn as_inner(&self) -> &fs_imp::File {1290        &self.inner1291    }1292}1293impl FromInner<fs_imp::File> for File {1294    fn from_inner(f: fs_imp::File) -> File {1295        File { inner: f }1296    }1297}1298impl IntoInner<fs_imp::File> for File {1299    fn into_inner(self) -> fs_imp::File {1300        self.inner1301    }1302}13031304#[stable(feature = "rust1", since = "1.0.0")]1305impl fmt::Debug for File {1306    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {1307        self.inner.fmt(f)1308    }1309}13101311/// Indicates how much extra capacity is needed to read the rest of the file.1312fn buffer_capacity_required(mut file: &File) -> Option<usize> {1313    let size = file.metadata().map(|m| m.len()).ok()?;1314    let pos = file.stream_position().ok()?;1315    // Don't worry about `usize` overflow because reading will fail regardless1316    // in that case.1317    Some(size.saturating_sub(pos) as usize)1318}13191320#[stable(feature = "rust1", since = "1.0.0")]1321impl Read for &File {1322    /// Reads some bytes from the file.1323    ///1324    /// See [`Read::read`] docs for more info.1325    ///1326    /// # Platform-specific behavior1327    ///1328    /// This function currently corresponds to the `read` function on Unix and1329    /// the `NtReadFile` function on Windows. Note that this [may change in1330    /// the future][changes].1331    ///1332    /// [changes]: io#platform-specific-behavior1333    #[inline]1334    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {1335        self.inner.read(buf)1336    }13371338    /// Like `read`, except that it reads into a slice of buffers.1339    ///1340    /// See [`Read::read_vectored`] docs for more info.1341    ///1342    /// # Platform-specific behavior1343    ///1344    /// This function currently corresponds to the `readv` function on Unix and1345    /// falls back to the `read` implementation on Windows. Note that this1346    /// [may change in the future][changes].1347    ///1348    /// [changes]: io#platform-specific-behavior1349    #[inline]1350    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {1351        self.inner.read_vectored(bufs)1352    }13531354    #[inline]1355    fn read_buf(&mut self, cursor: BorrowedCursor<'_, u8>) -> io::Result<()> {1356        self.inner.read_buf(cursor)1357    }13581359    /// Determines if `File` has an efficient `read_vectored` implementation.1360    ///1361    /// See [`Read::is_read_vectored`] docs for more info.1362    ///1363    /// # Platform-specific behavior1364    ///1365    /// This function currently returns `true` on Unix and `false` on Windows.1366    /// Note that this [may change in the future][changes].1367    ///1368    /// [changes]: io#platform-specific-behavior1369    #[inline]1370    fn is_read_vectored(&self) -> bool {1371        self.inner.is_read_vectored()1372    }13731374    // Reserves space in the buffer based on the file size when available.1375    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {1376        let size = buffer_capacity_required(self);1377        buf.try_reserve(size.unwrap_or(0))?;1378        io::default_read_to_end(self, buf, size)1379    }13801381    // Reserves space in the buffer based on the file size when available.1382    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {1383        let size = buffer_capacity_required(self);1384        buf.try_reserve(size.unwrap_or(0))?;1385        io::default_read_to_string(self, buf, size)1386    }1387}1388#[stable(feature = "rust1", since = "1.0.0")]1389impl Write for &File {1390    /// Writes some bytes to the file.1391    ///1392    /// See [`Write::write`] docs for more info.1393    ///1394    /// # Platform-specific behavior1395    ///1396    /// This function currently corresponds to the `write` function on Unix and1397    /// the `NtWriteFile` function on Windows. Note that this [may change in1398    /// the future][changes].1399    ///1400    /// [changes]: io#platform-specific-behavior1401    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {1402        self.inner.write(buf)1403    }14041405    /// Like `write`, except that it writes into a slice of buffers.1406    ///1407    /// See [`Write::write_vectored`] docs for more info.1408    ///1409    /// # Platform-specific behavior1410    ///1411    /// This function currently corresponds to the `writev` function on Unix1412    /// and falls back to the `write` implementation on Windows. Note that this1413    /// [may change in the future][changes].1414    ///1415    /// [changes]: io#platform-specific-behavior1416    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {1417        self.inner.write_vectored(bufs)1418    }14191420    /// Determines if `File` has an efficient `write_vectored` implementation.1421    ///1422    /// See [`Write::is_write_vectored`] docs for more info.1423    ///1424    /// # Platform-specific behavior1425    ///1426    /// This function currently returns `true` on Unix and `false` on Windows.1427    /// Note that this [may change in the future][changes].1428    ///1429    /// [changes]: io#platform-specific-behavior1430    #[inline]1431    fn is_write_vectored(&self) -> bool {1432        self.inner.is_write_vectored()1433    }14341435    /// Flushes the file, ensuring that all intermediately buffered contents1436    /// reach their destination.1437    ///1438    /// See [`Write::flush`] docs for more info.1439    ///1440    /// # Platform-specific behavior1441    ///1442    /// Since a `File` structure doesn't contain any buffers, this function is1443    /// currently a no-op on Unix and Windows. Note that this [may change in1444    /// the future][changes].1445    ///1446    /// [changes]: io#platform-specific-behavior1447    #[inline]1448    fn flush(&mut self) -> io::Result<()> {1449        self.inner.flush()1450    }1451}1452#[stable(feature = "rust1", since = "1.0.0")]1453impl Seek for &File {1454    /// Seek to an offset, in bytes in a file.1455    ///1456    /// See [`Seek::seek`] docs for more info.1457    ///1458    /// # Platform-specific behavior1459    ///1460    /// This function currently corresponds to the `lseek64` function on Unix1461    /// and the `SetFilePointerEx` function on Windows. Note that this [may1462    /// change in the future][changes].1463    ///1464    /// [changes]: io#platform-specific-behavior1465    fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {1466        self.inner.seek(pos)1467    }14681469    /// Returns the length of this file (in bytes).1470    ///1471    /// See [`Seek::stream_len`] docs for more info.1472    ///1473    /// # Platform-specific behavior1474    ///1475    /// This function currently corresponds to the `statx` function on Linux1476    /// (with fallbacks) and the `GetFileSizeEx` function on Windows. Note that1477    /// this [may change in the future][changes].1478    ///1479    /// [changes]: io#platform-specific-behavior1480    fn stream_len(&mut self) -> io::Result<u64> {1481        if let Some(result) = self.inner.size() {1482            return result;1483        }1484        io::stream_len_default(self)1485    }14861487    fn stream_position(&mut self) -> io::Result<u64> {1488        self.inner.tell()1489    }1490}14911492#[stable(feature = "rust1", since = "1.0.0")]1493impl Read for File {1494    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {1495        (&*self).read(buf)1496    }1497    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {1498        (&*self).read_vectored(bufs)1499    }1500    fn read_buf(&mut self, cursor: BorrowedCursor<'_, u8>) -> io::Result<()> {1501        (&*self).read_buf(cursor)1502    }1503    #[inline]1504    fn is_read_vectored(&self) -> bool {1505        (&&*self).is_read_vectored()1506    }1507    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {1508        (&*self).read_to_end(buf)1509    }1510    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {1511        (&*self).read_to_string(buf)1512    }1513}1514#[stable(feature = "rust1", since = "1.0.0")]1515impl Write for File {1516    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {1517        (&*self).write(buf)1518    }1519    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {1520        (&*self).write_vectored(bufs)1521    }1522    #[inline]1523    fn is_write_vectored(&self) -> bool {1524        (&&*self).is_write_vectored()1525    }1526    #[inline]1527    fn flush(&mut self) -> io::Result<()> {1528        (&*self).flush()1529    }1530}1531#[stable(feature = "rust1", since = "1.0.0")]1532impl Seek for File {1533    fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {1534        (&*self).seek(pos)1535    }1536    fn stream_len(&mut self) -> io::Result<u64> {1537        (&*self).stream_len()1538    }1539    fn stream_position(&mut self) -> io::Result<u64> {1540        (&*self).stream_position()1541    }1542}1543impl crate::io::IoHandle for File {}15441545impl Dir {1546    /// Attempts to open a directory at `path` in read-only mode.1547    ///1548    /// # Errors1549    ///1550    /// This function will return an error if `path` does not point to an existing directory.1551    /// Other errors may also be returned according to [`OpenOptions::open`].1552    ///1553    /// # Examples1554    ///1555    /// ```no_run1556    /// #![feature(dirfd)]1557    /// use std::{fs::Dir, io};1558    ///1559    /// fn main() -> std::io::Result<()> {1560    ///     let dir = Dir::open("foo")?;1561    ///     let mut f = dir.open_file("bar.txt")?;1562    ///     let contents = io::read_to_string(f)?;1563    ///     assert_eq!(contents, "Hello, world!");1564    ///     Ok(())1565    /// }1566    /// ```1567    #[unstable(feature = "dirfd", issue = "120426")]1568    pub fn open<P: AsRef<Path>>(path: P) -> io::Result<Self> {1569        fs_imp::Dir::open(path.as_ref(), &OpenOptions::new().read(true).0)1570            .map(|inner| Self { inner })1571    }15721573    /// Attempts to open a file in read-only mode relative to this directory.1574    ///1575    /// # Errors1576    ///1577    /// This function will return an error if `path` does not point to an existing file.1578    /// Other errors may also be returned according to [`OpenOptions::open`].1579    ///1580    /// # Examples1581    ///1582    /// ```no_run1583    /// #![feature(dirfd)]1584    /// use std::{fs::Dir, io};1585    ///1586    /// fn main() -> std::io::Result<()> {1587    ///     let dir = Dir::open("foo")?;1588    ///     let mut f = dir.open_file("bar.txt")?;1589    ///     let contents = io::read_to_string(f)?;1590    ///     assert_eq!(contents, "Hello, world!");1591    ///     Ok(())1592    /// }1593    /// ```1594    #[unstable(feature = "dirfd", issue = "120426")]1595    pub fn open_file<P: AsRef<Path>>(&self, path: P) -> io::Result<File> {1596        self.inner1597            .open_file(path.as_ref(), &OpenOptions::new().read(true).0)1598            .map(|f| File { inner: f })1599    }16001601    /// Queries metadata about the underlying directory.1602    ///1603    /// # Examples1604    ///1605    /// ```no_run1606    /// #![feature(dirfd)]1607    /// use std::fs::Dir;1608    ///1609    /// fn main() -> std::io::Result<()> {1610    ///     let dir = Dir::open("foo")?;1611    ///     let metadata = dir.metadata()?;1612    ///     Ok(())1613    /// }1614    /// ```1615    #[unstable(feature = "dirfd", issue = "120426")]1616    pub fn metadata(&self) -> io::Result<Metadata> {1617        self.inner.metadata().map(Metadata)1618    }1619}16201621impl AsInner<fs_imp::Dir> for Dir {1622    #[inline]1623    fn as_inner(&self) -> &fs_imp::Dir {1624        &self.inner1625    }1626}1627impl FromInner<fs_imp::Dir> for Dir {1628    fn from_inner(f: fs_imp::Dir) -> Dir {1629        Dir { inner: f }1630    }1631}1632impl IntoInner<fs_imp::Dir> for Dir {1633    fn into_inner(self) -> fs_imp::Dir {1634        self.inner1635    }1636}16371638#[unstable(feature = "dirfd", issue = "120426")]1639impl fmt::Debug for Dir {1640    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {1641        self.inner.fmt(f)1642    }1643}16441645impl OpenOptions {1646    /// Creates a blank new set of options ready for configuration.1647    ///1648    /// All options are initially set to `false`.1649    ///1650    /// # Examples1651    ///1652    /// ```no_run1653    /// use std::fs::OpenOptions;1654    ///1655    /// let mut options = OpenOptions::new();1656    /// let file = options.read(true).open("foo.txt");1657    /// ```1658    #[cfg_attr(not(test), rustc_diagnostic_item = "open_options_new")]1659    #[stable(feature = "rust1", since = "1.0.0")]1660    #[must_use]1661    pub fn new() -> Self {1662        OpenOptions(fs_imp::OpenOptions::new())1663    }16641665    /// Sets the option for read access.1666    ///1667    /// This option, when true, will indicate that the file should be1668    /// `read`-able if opened.1669    ///1670    /// # Examples1671    ///1672    /// ```no_run1673    /// use std::fs::OpenOptions;1674    ///1675    /// let file = OpenOptions::new().read(true).open("foo.txt");1676    /// ```1677    #[stable(feature = "rust1", since = "1.0.0")]1678    pub fn read(&mut self, read: bool) -> &mut Self {1679        self.0.read(read);1680        self1681    }16821683    /// Sets the option for write access.1684    ///1685    /// This option, when true, will indicate that the file should be1686    /// `write`-able if opened.1687    ///1688    /// If the file already exists, any write calls on it will overwrite its1689    /// contents, without truncating it.1690    ///1691    /// # Examples1692    ///1693    /// ```no_run1694    /// use std::fs::OpenOptions;1695    ///1696    /// let file = OpenOptions::new().write(true).open("foo.txt");1697    /// ```1698    #[stable(feature = "rust1", since = "1.0.0")]1699    pub fn write(&mut self, write: bool) -> &mut Self {1700        self.0.write(write);1701        self1702    }17031704    /// Sets the option for the append mode.1705    ///1706    /// This option, when true, means that writes will append to a file instead1707    /// of overwriting previous contents.1708    /// Note that setting `.write(true).append(true)` has the same effect as1709    /// setting only `.append(true)`.1710    ///1711    /// Append mode guarantees that writes will be positioned at the current end of file,1712    /// even when there are other processes or threads appending to the same file. This is1713    /// unlike <code>[seek]\([SeekFrom]::[End]\(0))</code> followed by `write()`, which1714    /// has a race between seeking and writing during which another writer can write, with1715    /// our `write()` overwriting their data.1716    ///1717    /// Keep in mind that this does not necessarily guarantee that data appended by1718    /// different processes or threads does not interleave. The amount of data accepted a1719    /// single `write()` call depends on the operating system and file system. A1720    /// successful `write()` is allowed to write only part of the given data, so even if1721    /// you're careful to provide the whole message in a single call to `write()`, there1722    /// is no guarantee that it will be written out in full. If you rely on the filesystem1723    /// accepting the message in a single write, make sure that all data that belongs1724    /// together is written in one operation. This can be done by concatenating strings1725    /// before passing them to [`write()`].1726    ///1727    /// If a file is opened with both read and append access, beware that after1728    /// opening, and after every write, the position for reading may be set at the1729    /// end of the file. So, before writing, save the current position (using1730    /// <code>[Seek]::[stream_position]</code>), and restore it before the next read.1731    ///1732    /// ## Note1733    ///1734    /// This function doesn't create the file if it doesn't exist. Use the1735    /// [`OpenOptions::create`] method to do so.1736    ///1737    /// [`write()`]: Write::write "io::Write::write"1738    /// [`flush()`]: Write::flush "io::Write::flush"1739    /// [stream_position]: Seek::stream_position "io::Seek::stream_position"1740    /// [seek]: Seek::seek "io::Seek::seek"1741    /// [Current]: SeekFrom::Current "io::SeekFrom::Current"1742    /// [End]: SeekFrom::End "io::SeekFrom::End"1743    ///1744    /// # Examples1745    ///1746    /// ```no_run1747    /// use std::fs::OpenOptions;1748    ///1749    /// let file = OpenOptions::new().append(true).open("foo.txt");1750    /// ```1751    #[stable(feature = "rust1", since = "1.0.0")]1752    pub fn append(&mut self, append: bool) -> &mut Self {1753        self.0.append(append);1754        self1755    }17561757    /// Sets the option for truncating a previous file.1758    ///1759    /// If a file is successfully opened with this option set to true, it will truncate1760    /// the file to 0 length if it already exists.1761    ///1762    /// The file must be opened with write access for truncate to work.1763    ///1764    /// # Examples1765    ///1766    /// ```no_run1767    /// use std::fs::OpenOptions;1768    ///1769    /// let file = OpenOptions::new().write(true).truncate(true).open("foo.txt");1770    /// ```1771    #[stable(feature = "rust1", since = "1.0.0")]1772    pub fn truncate(&mut self, truncate: bool) -> &mut Self {1773        self.0.truncate(truncate);1774        self1775    }17761777    /// Sets the option to create a new file, or open it if it already exists.1778    ///1779    /// In order for the file to be created, [`OpenOptions::write`] or1780    /// [`OpenOptions::append`] access must be used.1781    ///1782    /// See also [`std::fs::write()`][self::write] for a simple function to1783    /// create a file with some given data.1784    ///1785    /// # Errors1786    ///1787    /// If `.create(true)` is set without `.write(true)` or `.append(true)`,1788    /// calling [`open`](Self::open) will fail with [`InvalidInput`](io::ErrorKind::InvalidInput) error.1789    /// # Examples1790    ///1791    /// ```no_run1792    /// use std::fs::OpenOptions;1793    ///1794    /// let file = OpenOptions::new().write(true).create(true).open("foo.txt");1795    /// ```1796    #[stable(feature = "rust1", since = "1.0.0")]1797    pub fn create(&mut self, create: bool) -> &mut Self {1798        self.0.create(create);1799        self1800    }18011802    /// Sets the option to create a new file, failing if it already exists.1803    ///1804    /// No file is allowed to exist at the target location, also no (dangling) symlink. In this1805    /// way, if the call succeeds, the file returned is guaranteed to be new.1806    /// If a file exists at the target location, creating a new file will fail with [`AlreadyExists`]1807    /// or another error based on the situation. See [`OpenOptions::open`] for a1808    /// non-exhaustive list of likely errors.1809    ///1810    /// This option is useful because it is atomic. Otherwise between checking1811    /// whether a file exists and creating a new one, the file may have been1812    /// created by another process (a [TOCTOU] race condition / attack).1813    ///1814    /// If `.create_new(true)` is set, [`.create()`] and [`.truncate()`] are1815    /// ignored.1816    ///1817    /// The file must be opened with write or append access in order to create1818    /// a new file.1819    ///1820    /// [`.create()`]: OpenOptions::create1821    /// [`.truncate()`]: OpenOptions::truncate1822    /// [`AlreadyExists`]: io::ErrorKind::AlreadyExists1823    /// [TOCTOU]: self#time-of-check-to-time-of-use-toctou1824    ///1825    /// # Examples1826    ///1827    /// ```no_run1828    /// use std::fs::OpenOptions;1829    ///1830    /// let file = OpenOptions::new().write(true)1831    ///                              .create_new(true)1832    ///                              .open("foo.txt");1833    /// ```1834    #[stable(feature = "expand_open_options2", since = "1.9.0")]1835    pub fn create_new(&mut self, create_new: bool) -> &mut Self {1836        self.0.create_new(create_new);1837        self1838    }18391840    /// Opens a file at `path` with the options specified by `self`.1841    ///1842    /// # Errors1843    ///1844    /// This function will return an error under a number of different1845    /// circumstances. Some of these error conditions are listed here, together1846    /// with their [`io::ErrorKind`]. The mapping to [`io::ErrorKind`]s is not1847    /// part of the compatibility contract of the function.1848    ///1849    /// * [`NotFound`]: The specified file does not exist and neither `create`1850    ///   or `create_new` is set.1851    /// * [`NotFound`]: One of the directory components of the file path does1852    ///   not exist.1853    /// * [`PermissionDenied`]: The user lacks permission to get the specified1854    ///   access rights for the file.1855    /// * [`PermissionDenied`]: The user lacks permission to open one of the1856    ///   directory components of the specified path.1857    /// * [`AlreadyExists`]: `create_new` was specified and the file already1858    ///   exists.1859    /// * [`InvalidInput`]: Invalid combinations of open options (truncate1860    ///   without write access, create without write or append access,1861    ///   no access mode set, etc.).1862    ///1863    /// The following errors don't match any existing [`io::ErrorKind`] at the moment:1864    /// * One of the directory components of the specified file path1865    ///   was not, in fact, a directory.1866    /// * Filesystem-level errors: full disk, write permission1867    ///   requested on a read-only file system, exceeded disk quota, too many1868    ///   open files, too long filename, too many symbolic links in the1869    ///   specified path (Unix-like systems only), etc.1870    ///1871    /// # Examples1872    ///1873    /// ```no_run1874    /// use std::fs::OpenOptions;1875    ///1876    /// let file = OpenOptions::new().read(true).open("foo.txt");1877    /// ```1878    ///1879    /// [`AlreadyExists`]: io::ErrorKind::AlreadyExists1880    /// [`InvalidInput`]: io::ErrorKind::InvalidInput1881    /// [`NotFound`]: io::ErrorKind::NotFound1882    /// [`PermissionDenied`]: io::ErrorKind::PermissionDenied1883    #[stable(feature = "rust1", since = "1.0.0")]1884    pub fn open<P: AsRef<Path>>(&self, path: P) -> io::Result<File> {1885        self._open(path.as_ref())1886    }18871888    fn _open(&self, path: &Path) -> io::Result<File> {1889        fs_imp::File::open(path, &self.0).map(|inner| File { inner })1890    }1891}18921893impl AsInner<fs_imp::OpenOptions> for OpenOptions {1894    #[inline]1895    fn as_inner(&self) -> &fs_imp::OpenOptions {1896        &self.01897    }1898}18991900impl AsInnerMut<fs_imp::OpenOptions> for OpenOptions {1901    #[inline]1902    fn as_inner_mut(&mut self) -> &mut fs_imp::OpenOptions {1903        &mut self.01904    }1905}19061907impl Metadata {1908    /// Returns the file type for this metadata.1909    ///1910    /// # Examples1911    ///1912    /// ```no_run1913    /// fn main() -> std::io::Result<()> {1914    ///     use std::fs;1915    ///1916    ///     let metadata = fs::metadata("foo.txt")?;1917    ///1918    ///     println!("{:?}", metadata.file_type());1919    ///     Ok(())1920    /// }1921    /// ```1922    #[must_use]1923    #[stable(feature = "file_type", since = "1.1.0")]1924    pub fn file_type(&self) -> FileType {1925        FileType(self.0.file_type())1926    }19271928    /// Returns `true` if this metadata is for a directory. The1929    /// result is mutually exclusive to the result of1930    /// [`Metadata::is_file`], and will be false for symlink metadata1931    /// obtained from [`symlink_metadata`].1932    ///1933    /// # Examples1934    ///1935    /// ```no_run1936    /// fn main() -> std::io::Result<()> {1937    ///     use std::fs;1938    ///1939    ///     let metadata = fs::metadata("foo.txt")?;1940    ///1941    ///     assert!(!metadata.is_dir());1942    ///     Ok(())1943    /// }1944    /// ```1945    #[must_use]1946    #[stable(feature = "rust1", since = "1.0.0")]1947    pub fn is_dir(&self) -> bool {1948        self.file_type().is_dir()1949    }19501951    /// Returns `true` if this metadata is for a regular file. The1952    /// result is mutually exclusive to the result of1953    /// [`Metadata::is_dir`], and will be false for symlink metadata1954    /// obtained from [`symlink_metadata`].1955    ///1956    /// When the goal is simply to read from (or write to) the source, the most1957    /// reliable way to test the source can be read (or written to) is to open1958    /// it. Only using `is_file` can break workflows like `diff <( prog_a )` on1959    /// a Unix-like system for example. See [`File::open`] or1960    /// [`OpenOptions::open`] for more information.1961    ///1962    /// # Examples1963    ///1964    /// ```no_run1965    /// use std::fs;1966    ///1967    /// fn main() -> std::io::Result<()> {1968    ///     let metadata = fs::metadata("foo.txt")?;1969    ///1970    ///     assert!(metadata.is_file());1971    ///     Ok(())1972    /// }1973    /// ```1974    #[must_use]1975    #[stable(feature = "rust1", since = "1.0.0")]1976    pub fn is_file(&self) -> bool {1977        self.file_type().is_file()1978    }19791980    /// Returns `true` if this metadata is for a symbolic link.1981    ///1982    /// # Examples1983    ///1984    #[cfg_attr(unix, doc = "```no_run")]1985    #[cfg_attr(not(unix), doc = "```ignore")]1986    /// use std::fs;1987    /// use std::path::Path;1988    /// use std::os::unix::fs::symlink;1989    ///1990    /// fn main() -> std::io::Result<()> {1991    ///     let link_path = Path::new("link");1992    ///     symlink("/origin_does_not_exist/", link_path)?;1993    ///1994    ///     let metadata = fs::symlink_metadata(link_path)?;1995    ///1996    ///     assert!(metadata.is_symlink());1997    ///     Ok(())1998    /// }1999    /// ```2000    #[must_use]

Findings

✓ No findings reported for this file.

Get this view in your editor

Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.