library/std/src/fs.rs RUST 3,674 lines View on github.com → Search inside
File is large — showing lines 1–2,000 of 3,674.
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        target_os = "l4re",41    ))42))]43mod tests;4445use crate::ffi::OsString;46use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write};47use crate::path::{Path, PathBuf};48use crate::sys::{AsInner, AsInnerMut, FromInner, IntoInner, fs as fs_imp};49use crate::time::SystemTime;50use crate::{error, fmt};5152/// An object providing access to an open file on the filesystem.53///54/// An instance of a `File` can be read and/or written depending on what options55/// it was opened with. Files also implement [`Seek`] to alter the logical cursor56/// that the file contains internally.57///58/// Files are automatically closed when they go out of scope.  Errors detected59/// on closing are ignored by the implementation of `Drop`.  Use the method60/// [`sync_all`] if these errors must be manually handled.61///62/// `File` does not buffer reads and writes. For efficiency, consider wrapping the63/// file in a [`BufReader`] or [`BufWriter`] when performing many small [`read`]64/// or [`write`] calls, unless unbuffered reads and writes are required.65///66/// # Examples67///68/// Creates a new file and write bytes to it (you can also use [`write`]):69///70/// ```no_run71/// use std::fs::File;72/// use std::io::prelude::*;73///74/// fn main() -> std::io::Result<()> {75///     let mut file = File::create("foo.txt")?;76///     file.write_all(b"Hello, world!")?;77///     Ok(())78/// }79/// ```80///81/// Reads the contents of a file into a [`String`] (you can also use [`read`]):82///83/// ```no_run84/// use std::fs::File;85/// use std::io::prelude::*;86///87/// fn main() -> std::io::Result<()> {88///     let mut file = File::open("foo.txt")?;89///     let mut contents = String::new();90///     file.read_to_string(&mut contents)?;91///     assert_eq!(contents, "Hello, world!");92///     Ok(())93/// }94/// ```95///96/// Using a buffered [`Read`]er:97///98/// ```no_run99/// use std::fs::File;100/// use std::io::BufReader;101/// use std::io::prelude::*;102///103/// fn main() -> std::io::Result<()> {104///     let file = File::open("foo.txt")?;105///     let mut buf_reader = BufReader::new(file);106///     let mut contents = String::new();107///     buf_reader.read_to_string(&mut contents)?;108///     assert_eq!(contents, "Hello, world!");109///     Ok(())110/// }111/// ```112///113/// Note that, although read and write methods require a `&mut File`, because114/// of the interfaces for [`Read`] and [`Write`], the holder of a `&File` can115/// still modify the file, either through methods that take `&File` or by116/// retrieving the underlying OS object and modifying the file that way.117/// Additionally, many operating systems allow concurrent modification of files118/// by different processes. Avoid assuming that holding a `&File` means that the119/// file will not change.120///121/// # Platform-specific behavior122///123/// On Windows, the implementation of [`Read`] and [`Write`] traits for `File`124/// perform synchronous I/O operations. Therefore the underlying file must not125/// have been opened for asynchronous I/O (e.g. by using `FILE_FLAG_OVERLAPPED`).126///127/// [`BufReader`]: io::BufReader128/// [`BufWriter`]: io::BufWriter129/// [`sync_all`]: File::sync_all130/// [`write`]: File::write131/// [`read`]: File::read132#[stable(feature = "rust1", since = "1.0.0")]133#[cfg_attr(not(test), rustc_diagnostic_item = "File")]134#[diagnostic::on_move(note = "you can use `File::try_clone` to duplicate a `File` instance")]135pub struct File {136    inner: fs_imp::File,137}138139/// An enumeration of possible errors which can occur while trying to acquire a lock140/// from the [`try_lock`] method and [`try_lock_shared`] method on a [`File`].141///142/// [`try_lock`]: File::try_lock143/// [`try_lock_shared`]: File::try_lock_shared144#[stable(feature = "file_lock", since = "1.89.0")]145pub enum TryLockError {146    /// The lock could not be acquired due to an I/O error on the file. The standard library will147    /// not return an [`ErrorKind::WouldBlock`] error inside [`TryLockError::Error`]148    ///149    /// [`ErrorKind::WouldBlock`]: io::ErrorKind::WouldBlock150    Error(io::Error),151    /// The lock could not be acquired at this time because it is held by another handle/process.152    WouldBlock,153}154155/// An object providing access to a directory on the filesystem.156///157/// Directories are automatically closed when they go out of scope.  Errors detected158/// on closing are ignored by the implementation of `Drop`.159///160/// # Platform-specific behavior161///162/// On supported systems (including Windows and some UNIX-based OSes), this function acquires a163/// handle/file descriptor for the directory. This allows functions like [`Dir::open_file`] to164/// avoid [TOCTOU] errors when the directory itself is being moved.165///166/// On other systems, it stores an absolute path (see [`canonicalize()`]). In the latter case, no167/// [TOCTOU] guarantees are made.168///169/// # Examples170///171/// Opens a directory and then a file inside it.172///173/// ```no_run174/// #![feature(dirfd)]175/// use std::{fs::Dir, io};176///177/// fn main() -> std::io::Result<()> {178///     let dir = Dir::open("foo")?;179///     let mut file = dir.open_file("bar.txt")?;180///     let contents = io::read_to_string(file)?;181///     assert_eq!(contents, "Hello, world!");182///     Ok(())183/// }184/// ```185///186/// [TOCTOU]: self#time-of-check-to-time-of-use-toctou187#[unstable(feature = "dirfd", issue = "120426")]188#[cfg_attr(not(test), rustc_diagnostic_item = "FsDir")]189pub struct Dir {190    inner: fs_imp::Dir,191}192193/// Metadata information about a file.194///195/// This structure is returned from the [`metadata`] or196/// [`symlink_metadata`] function or method and represents known197/// metadata about a file such as its permissions, size, modification198/// times, etc.199#[stable(feature = "rust1", since = "1.0.0")]200#[derive(Clone)]201#[cfg_attr(not(test), rustc_diagnostic_item = "FsMetadata")]202pub struct Metadata(fs_imp::FileAttr);203204/// Iterator over the entries in a directory.205///206/// This iterator is returned from the [`read_dir`] function of this module and207/// will yield instances of <code>[io::Result]<[DirEntry]></code>. Through a [`DirEntry`]208/// information like the entry's path and possibly other metadata can be209/// learned.210///211/// The order in which this iterator returns entries is platform and filesystem212/// dependent.213///214/// # Errors215/// This [`io::Result`] will be an [`Err`] if an error occurred while fetching216/// the next entry from the OS.217#[stable(feature = "rust1", since = "1.0.0")]218#[derive(Debug)]219#[cfg_attr(not(test), rustc_diagnostic_item = "FsReadDir")]220pub struct ReadDir(fs_imp::ReadDir);221222/// Entries returned by the [`ReadDir`] iterator.223///224/// An instance of `DirEntry` represents an entry inside of a directory on the225/// filesystem. Each entry can be inspected via methods to learn about the full226/// path or possibly other metadata through per-platform extension traits.227///228/// # Platform-specific behavior229///230/// On Unix, the `DirEntry` struct contains an internal reference to the open231/// directory. Holding `DirEntry` objects will consume a file handle even232/// after the `ReadDir` iterator is dropped.233///234/// Note that this [may change in the future][changes].235///236/// [changes]: io#platform-specific-behavior237#[stable(feature = "rust1", since = "1.0.0")]238#[cfg_attr(not(test), rustc_diagnostic_item = "FsDirEntry")]239pub struct DirEntry(fs_imp::DirEntry);240241/// Options and flags which can be used to configure how a file is opened.242///243/// This builder exposes the ability to configure how a [`File`] is opened and244/// what operations are permitted on the open file. The [`File::open`] and245/// [`File::create`] methods are aliases for commonly used options using this246/// builder.247///248/// Generally speaking, when using `OpenOptions`, you'll first call249/// [`OpenOptions::new`], then chain calls to methods to set each option, then250/// call [`OpenOptions::open`], passing the path of the file you're trying to251/// open. This will give you a [`io::Result`] with a [`File`] inside that you252/// can further operate on.253///254/// # Examples255///256/// Opening a file to read:257///258/// ```no_run259/// use std::fs::OpenOptions;260///261/// let file = OpenOptions::new().read(true).open("foo.txt");262/// ```263///264/// Opening a file for both reading and writing, as well as creating it if it265/// doesn't exist:266///267/// ```no_run268/// use std::fs::OpenOptions;269///270/// let file = OpenOptions::new()271///             .read(true)272///             .write(true)273///             .create(true)274///             .open("foo.txt");275/// ```276#[derive(Clone, Debug)]277#[stable(feature = "rust1", since = "1.0.0")]278#[cfg_attr(not(test), rustc_diagnostic_item = "FsOpenOptions")]279pub struct OpenOptions(fs_imp::OpenOptions);280281/// Representation of the various timestamps on a file.282#[derive(Copy, Clone, Debug, Default)]283#[stable(feature = "file_set_times", since = "1.75.0")]284#[must_use = "must be applied to a file via `File::set_times` to have any effect"]285pub struct FileTimes(fs_imp::FileTimes);286287/// Representation of the various permissions on a file.288///289/// This module only currently provides one bit of information,290/// [`Permissions::readonly`], which is exposed on all currently supported291/// platforms. Unix-specific functionality, such as mode bits, is available292/// through the [`PermissionsExt`] trait.293///294/// [`PermissionsExt`]: crate::os::unix::fs::PermissionsExt295#[derive(Clone, PartialEq, Eq, Debug)]296#[stable(feature = "rust1", since = "1.0.0")]297#[cfg_attr(not(test), rustc_diagnostic_item = "FsPermissions")]298pub struct Permissions(fs_imp::FilePermissions);299300/// A structure representing a type of file with accessors for each file type.301/// It is returned by [`Metadata::file_type`] method.302#[stable(feature = "file_type", since = "1.1.0")]303#[derive(Copy, Clone, PartialEq, Eq, Hash)]304#[cfg_attr(not(test), rustc_diagnostic_item = "FileType")]305pub struct FileType(fs_imp::FileType);306307/// A builder used to create directories in various manners.308///309/// This builder also supports platform-specific options.310#[stable(feature = "dir_builder", since = "1.6.0")]311#[cfg_attr(not(test), rustc_diagnostic_item = "DirBuilder")]312#[derive(Debug)]313pub struct DirBuilder {314    inner: fs_imp::DirBuilder,315    recursive: bool,316}317318/// Reads the entire contents of a file into a bytes vector.319///320/// This is a convenience function for using [`File::open`] and [`read_to_end`]321/// with fewer imports and without an intermediate variable.322///323/// [`read_to_end`]: Read::read_to_end324///325/// # Errors326///327/// This function will return an error if `path` does not already exist.328/// Other errors may also be returned according to [`OpenOptions::open`].329///330/// While reading from the file, this function handles [`io::ErrorKind::Interrupted`]331/// with automatic retries. See [io::Read] documentation for details.332///333/// # Examples334///335/// ```no_run336/// use std::fs;337///338/// fn main() -> Result<(), Box<dyn std::error::Error + 'static>> {339///     let data: Vec<u8> = fs::read("image.jpg")?;340///     assert_eq!(data[0..3], [0xFF, 0xD8, 0xFF]);341///     Ok(())342/// }343/// ```344#[stable(feature = "fs_read_write_bytes", since = "1.26.0")]345#[cfg_attr(not(test), rustc_diagnostic_item = "fs_read")]346pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {347    fn inner(path: &Path) -> io::Result<Vec<u8>> {348        let mut file = File::open(path)?;349        let size = file.metadata().map(|m| usize::try_from(m.len()).unwrap_or(usize::MAX)).ok();350        let mut bytes = Vec::try_with_capacity(size.unwrap_or(0))?;351        io::default_read_to_end(&mut file, &mut bytes, size)?;352        Ok(bytes)353    }354    inner(path.as_ref())355}356357/// Reads the entire contents of a file into a string.358///359/// This is a convenience function for using [`File::open`] and [`read_to_string`]360/// with fewer imports and without an intermediate variable.361///362/// [`read_to_string`]: Read::read_to_string363///364/// # Errors365///366/// This function will return an error if `path` does not already exist.367/// Other errors may also be returned according to [`OpenOptions::open`].368///369/// If the contents of the file are not valid UTF-8, then an error will also be370/// returned.371///372/// While reading from the file, this function handles [`io::ErrorKind::Interrupted`]373/// with automatic retries. See [io::Read] documentation for details.374///375/// # Examples376///377/// ```no_run378/// use std::fs;379/// use std::error::Error;380///381/// fn main() -> Result<(), Box<dyn Error>> {382///     let message: String = fs::read_to_string("message.txt")?;383///     println!("{}", message);384///     Ok(())385/// }386/// ```387#[stable(feature = "fs_read_write", since = "1.26.0")]388#[cfg_attr(not(test), rustc_diagnostic_item = "fs_read_to_string")]389pub fn read_to_string<P: AsRef<Path>>(path: P) -> io::Result<String> {390    fn inner(path: &Path) -> io::Result<String> {391        let mut file = File::open(path)?;392        let size = file.metadata().map(|m| usize::try_from(m.len()).unwrap_or(usize::MAX)).ok();393        let mut string = String::new();394        string.try_reserve_exact(size.unwrap_or(0))?;395        io::default_read_to_string(&mut file, &mut string, size)?;396        Ok(string)397    }398    inner(path.as_ref())399}400401/// Writes a slice as the entire contents of a file.402///403/// This function will create a file if it does not exist,404/// and will entirely replace its contents if it does.405///406/// Depending on the platform, this function may fail if the407/// full directory path does not exist.408///409/// This is a convenience function for using [`File::create`] and [`write_all`]410/// with fewer imports.411///412/// [`write_all`]: Write::write_all413///414/// # Examples415///416/// ```no_run417/// use std::fs;418///419/// fn main() -> std::io::Result<()> {420///     fs::write("foo.txt", b"Lorem ipsum")?;421///     fs::write("bar.txt", "dolor sit")?;422///     Ok(())423/// }424/// ```425#[stable(feature = "fs_read_write_bytes", since = "1.26.0")]426#[cfg_attr(not(test), rustc_diagnostic_item = "fs_write")]427pub fn write<P: AsRef<Path>, C: AsRef<[u8]>>(path: P, contents: C) -> io::Result<()> {428    fn inner(path: &Path, contents: &[u8]) -> io::Result<()> {429        File::create(path)?.write_all(contents)430    }431    inner(path.as_ref(), contents.as_ref())432}433434/// Changes the timestamps of the file or directory at the specified path.435///436/// This function will attempt to set the access and modification times437/// to the times specified. If the path refers to a symbolic link, this function438/// will follow the link and change the timestamps of the target file.439///440/// # Platform-specific behavior441///442/// This function currently corresponds to the `utimensat` function on Unix platforms, the443/// `setattrlist` function on Apple platforms, and the `SetFileTime` function on Windows.444///445/// # Errors446///447/// This function will return an error if the user lacks permission to change timestamps on the448/// target file or symlink. It may also return an error if the OS does not support it.449///450/// # Examples451///452/// ```no_run453/// use std::fs::{self, FileTimes};454/// use std::time::SystemTime;455///456/// fn main() -> std::io::Result<()> {457///     let now = SystemTime::now();458///     let times = FileTimes::new()459///         .set_accessed(now)460///         .set_modified(now);461///     fs::set_times("foo.txt", times)?;462///     Ok(())463/// }464/// ```465#[stable(feature = "fs_set_times", since = "1.99.0")]466#[doc(alias = "utimens")]467#[doc(alias = "utimes")]468#[doc(alias = "utime")]469#[cfg_attr(not(test), rustc_diagnostic_item = "fs_set_times")]470pub fn set_times<P: AsRef<Path>>(path: P, times: FileTimes) -> io::Result<()> {471    fs_imp::set_times(path.as_ref(), times.0)472}473474/// Changes the timestamps of the file or symlink at the specified path.475///476/// This function will attempt to set the access and modification times477/// to the times specified. Differ from `set_times`, if the path refers to a symbolic link,478/// this function will change the timestamps of the symlink itself, not the target file.479///480/// # Platform-specific behavior481///482/// This function currently corresponds to the `utimensat` function with `AT_SYMLINK_NOFOLLOW` on483/// Unix platforms, the `setattrlist` function with `FSOPT_NOFOLLOW` on Apple platforms, and the484/// `SetFileTime` function on Windows.485///486/// # Errors487///488/// This function will return an error if the user lacks permission to change timestamps on the489/// target file or symlink. It may also return an error if the OS does not support it.490///491/// # Examples492///493/// ```no_run494/// use std::fs::{self, FileTimes};495/// use std::time::SystemTime;496///497/// fn main() -> std::io::Result<()> {498///     let now = SystemTime::now();499///     let times = FileTimes::new()500///         .set_accessed(now)501///         .set_modified(now);502///     fs::set_times_nofollow("symlink.txt", times)?;503///     Ok(())504/// }505/// ```506#[stable(feature = "fs_set_times", since = "1.99.0")]507#[doc(alias = "utimensat")]508#[doc(alias = "lutimens")]509#[doc(alias = "lutimes")]510#[cfg_attr(not(test), rustc_diagnostic_item = "fs_set_times_nofollow")]511pub fn set_times_nofollow<P: AsRef<Path>>(path: P, times: FileTimes) -> io::Result<()> {512    fs_imp::set_times_nofollow(path.as_ref(), times.0)513}514515#[stable(feature = "file_lock", since = "1.89.0")]516impl error::Error for TryLockError {}517518#[stable(feature = "file_lock", since = "1.89.0")]519impl fmt::Debug for TryLockError {520    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {521        match self {522            TryLockError::Error(err) => err.fmt(f),523            TryLockError::WouldBlock => "WouldBlock".fmt(f),524        }525    }526}527528#[stable(feature = "file_lock", since = "1.89.0")]529impl fmt::Display for TryLockError {530    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {531        match self {532            TryLockError::Error(_) => "lock acquisition failed due to I/O error",533            TryLockError::WouldBlock => "lock acquisition failed because the operation would block",534        }535        .fmt(f)536    }537}538539#[stable(feature = "file_lock", since = "1.89.0")]540impl From<TryLockError> for io::Error {541    fn from(err: TryLockError) -> io::Error {542        match err {543            TryLockError::Error(err) => err,544            TryLockError::WouldBlock => io::ErrorKind::WouldBlock.into(),545        }546    }547}548549impl File {550    /// Attempts to open a file in read-only mode.551    ///552    /// See the [`OpenOptions::open`] method for more details.553    ///554    /// If you only need to read the entire file contents,555    /// consider [`std::fs::read()`][self::read] or556    /// [`std::fs::read_to_string()`][self::read_to_string] instead.557    ///558    /// # Errors559    ///560    /// This function will return an error if `path` does not already exist.561    /// Other errors may also be returned according to [`OpenOptions::open`].562    ///563    /// # Examples564    ///565    /// ```no_run566    /// use std::fs::File;567    /// use std::io::Read;568    ///569    /// fn main() -> std::io::Result<()> {570    ///     let mut f = File::open("foo.txt")?;571    ///     let mut data = vec![];572    ///     f.read_to_end(&mut data)?;573    ///     Ok(())574    /// }575    /// ```576    #[stable(feature = "rust1", since = "1.0.0")]577    pub fn open<P: AsRef<Path>>(path: P) -> io::Result<File> {578        OpenOptions::new().read(true).open(path.as_ref())579    }580581    /// Attempts to open a file in read-only mode with buffering.582    ///583    /// See the [`OpenOptions::open`] method, the [`BufReader`][io::BufReader] type,584    /// and the [`BufRead`][io::BufRead] trait for more details.585    ///586    /// If you only need to read the entire file contents,587    /// consider [`std::fs::read()`][self::read] or588    /// [`std::fs::read_to_string()`][self::read_to_string] instead.589    ///590    /// # Errors591    ///592    /// This function will return an error if `path` does not already exist,593    /// or if memory allocation fails for the new buffer.594    /// Other errors may also be returned according to [`OpenOptions::open`].595    ///596    /// # Examples597    ///598    /// ```no_run599    /// #![feature(file_buffered)]600    /// use std::fs::File;601    /// use std::io::BufRead;602    ///603    /// fn main() -> std::io::Result<()> {604    ///     let mut f = File::open_buffered("foo.txt")?;605    ///     assert!(f.capacity() > 0);606    ///     for (line, i) in f.lines().zip(1..) {607    ///         println!("{i:6}: {}", line?);608    ///     }609    ///     Ok(())610    /// }611    /// ```612    #[unstable(feature = "file_buffered", issue = "130804")]613    pub fn open_buffered<P: AsRef<Path>>(path: P) -> io::Result<io::BufReader<File>> {614        // Allocate the buffer *first* so we don't affect the filesystem otherwise.615        io::BufReader::try_new_with(|| File::open(path))616    }617618    /// Opens a file in write-only mode.619    ///620    /// This function will create a file if it does not exist,621    /// and will truncate it if it does.622    ///623    /// Depending on the platform, this function may fail if the624    /// full directory path does not exist.625    /// See the [`OpenOptions::open`] function for more details.626    ///627    /// See also [`std::fs::write()`][self::write] for a simple function to628    /// create a file with some given data.629    ///630    /// # Examples631    ///632    /// ```no_run633    /// use std::fs::File;634    /// use std::io::Write;635    ///636    /// fn main() -> std::io::Result<()> {637    ///     let mut f = File::create("foo.txt")?;638    ///     f.write_all(&1234_u32.to_be_bytes())?;639    ///     Ok(())640    /// }641    /// ```642    #[stable(feature = "rust1", since = "1.0.0")]643    pub fn create<P: AsRef<Path>>(path: P) -> io::Result<File> {644        OpenOptions::new().write(true).create(true).truncate(true).open(path.as_ref())645    }646647    /// Opens a file in write-only mode with buffering.648    ///649    /// This function will create a file if it does not exist,650    /// and will truncate it if it does.651    ///652    /// Depending on the platform, this function may fail if the653    /// full directory path does not exist.654    ///655    /// See the [`OpenOptions::open`] method and the656    /// [`BufWriter`][io::BufWriter] type for more details.657    ///658    /// See also [`std::fs::write()`][self::write] for a simple function to659    /// create a file with some given data.660    ///661    /// # Examples662    ///663    /// ```no_run664    /// #![feature(file_buffered)]665    /// use std::fs::File;666    /// use std::io::Write;667    ///668    /// fn main() -> std::io::Result<()> {669    ///     let mut f = File::create_buffered("foo.txt")?;670    ///     assert!(f.capacity() > 0);671    ///     for i in 0..100 {672    ///         writeln!(&mut f, "{i}")?;673    ///     }674    ///     f.flush()?;675    ///     Ok(())676    /// }677    /// ```678    #[unstable(feature = "file_buffered", issue = "130804")]679    pub fn create_buffered<P: AsRef<Path>>(path: P) -> io::Result<io::BufWriter<File>> {680        // Allocate the buffer *first* so we don't affect the filesystem otherwise.681        io::BufWriter::try_new_with(|| File::create(path))682    }683684    /// Creates a new file in read-write mode; error if the file exists.685    ///686    /// This function will create a file if it does not exist, or return an error if it does. This687    /// way, if the call succeeds, the file returned is guaranteed to be new.688    /// If a file exists at the target location, creating a new file will fail with [`AlreadyExists`]689    /// or another error based on the situation. See [`OpenOptions::open`] for a690    /// non-exhaustive list of likely errors.691    ///692    /// This option is useful because it is atomic. Otherwise between checking whether a file693    /// exists and creating a new one, the file may have been created by another process (a [TOCTOU]694    /// race condition / attack).695    ///696    /// This can also be written using697    /// `File::options().read(true).write(true).create_new(true).open(...)`.698    ///699    /// [`AlreadyExists`]: crate::io::ErrorKind::AlreadyExists700    /// [TOCTOU]: self#time-of-check-to-time-of-use-toctou701    ///702    /// # Examples703    ///704    /// ```no_run705    /// use std::fs::File;706    /// use std::io::Write;707    ///708    /// fn main() -> std::io::Result<()> {709    ///     let mut f = File::create_new("foo.txt")?;710    ///     f.write_all("Hello, world!".as_bytes())?;711    ///     Ok(())712    /// }713    /// ```714    #[stable(feature = "file_create_new", since = "1.77.0")]715    pub fn create_new<P: AsRef<Path>>(path: P) -> io::Result<File> {716        OpenOptions::new().read(true).write(true).create_new(true).open(path.as_ref())717    }718719    /// Returns a new OpenOptions object.720    ///721    /// This function returns a new OpenOptions object that you can use to722    /// open or create a file with specific options if `open()` or `create()`723    /// are not appropriate.724    ///725    /// It is equivalent to `OpenOptions::new()`, but allows you to write more726    /// readable code. Instead of727    /// `OpenOptions::new().append(true).open("example.log")`,728    /// you can write `File::options().append(true).open("example.log")`. This729    /// also avoids the need to import `OpenOptions`.730    ///731    /// See the [`OpenOptions::new`] function for more details.732    ///733    /// # Examples734    ///735    /// ```no_run736    /// use std::fs::File;737    /// use std::io::Write;738    ///739    /// fn main() -> std::io::Result<()> {740    ///     let mut f = File::options().append(true).open("example.log")?;741    ///     writeln!(&mut f, "new line")?;742    ///     Ok(())743    /// }744    /// ```745    #[must_use]746    #[stable(feature = "with_options", since = "1.58.0")]747    #[cfg_attr(not(test), rustc_diagnostic_item = "file_options")]748    pub fn options() -> OpenOptions {749        OpenOptions::new()750    }751752    /// Attempts to sync all OS-internal file content and metadata to disk.753    ///754    /// This function will attempt to ensure that all in-memory data reaches the755    /// filesystem before returning.756    ///757    /// This can be used to handle errors that would otherwise only be caught758    /// when the `File` is closed, as dropping a `File` will ignore all errors.759    /// Note, however, that `sync_all` is generally more expensive than closing760    /// a file by dropping it, because the latter is not required to block until761    /// the data has been written to the filesystem.762    ///763    /// If synchronizing the metadata is not required, use [`sync_data`] instead.764    ///765    /// [`sync_data`]: File::sync_data766    ///767    /// # Examples768    ///769    /// ```no_run770    /// use std::fs::File;771    /// use std::io::prelude::*;772    ///773    /// fn main() -> std::io::Result<()> {774    ///     let mut f = File::create("foo.txt")?;775    ///     f.write_all(b"Hello, world!")?;776    ///777    ///     f.sync_all()?;778    ///     Ok(())779    /// }780    /// ```781    #[stable(feature = "rust1", since = "1.0.0")]782    #[doc(alias = "fsync")]783    pub fn sync_all(&self) -> io::Result<()> {784        self.inner.fsync()785    }786787    /// This function is similar to [`sync_all`], except that it might not788    /// synchronize file metadata to the filesystem.789    ///790    /// This is intended for use cases that must synchronize content, but don't791    /// need the metadata on disk. The goal of this method is to reduce disk792    /// operations.793    ///794    /// Note that some platforms may simply implement this in terms of795    /// [`sync_all`].796    ///797    /// [`sync_all`]: File::sync_all798    ///799    /// # Examples800    ///801    /// ```no_run802    /// use std::fs::File;803    /// use std::io::prelude::*;804    ///805    /// fn main() -> std::io::Result<()> {806    ///     let mut f = File::create("foo.txt")?;807    ///     f.write_all(b"Hello, world!")?;808    ///809    ///     f.sync_data()?;810    ///     Ok(())811    /// }812    /// ```813    #[stable(feature = "rust1", since = "1.0.0")]814    #[doc(alias = "fdatasync")]815    pub fn sync_data(&self) -> io::Result<()> {816        self.inner.datasync()817    }818819    /// Acquire an exclusive lock on the file. Blocks until the lock can be acquired.820    ///821    /// This acquires an exclusive lock. No *other* file handle to this file, in this or any other822    /// process, may acquire another lock.823    /// If this file handle/descriptor, or a clone of it, already holds a lock, the exact behavior824    /// is unspecified and platform dependent, including the possibility that it will deadlock.825    /// However, if this method returns, then an exclusive lock is held.826    ///827    /// This lock may be advisory or mandatory. This lock is meant to interact with [`lock`],828    /// [`try_lock`], [`lock_shared`], [`try_lock_shared`], and [`unlock`]. Its interactions with829    /// other methods, such as [`read`] and [`write`] are platform specific, and it may or may not830    /// cause non-lockholders to block.831    ///832    /// If the file is not open for writing, it is unspecified whether this function returns an error.833    ///834    /// The lock will be released when this file (along with any other file descriptors/handles835    /// duplicated or inherited from it) is closed, or if the [`unlock`] method is called.836    ///837    /// # Platform-specific behavior838    ///839    /// This function currently corresponds to the `flock` function on Unix with the `LOCK_EX` flag,840    /// and the `LockFileEx` function on Windows with the `LOCKFILE_EXCLUSIVE_LOCK` flag. Note that,841    /// this [may change in the future][changes].842    ///843    /// On Windows, locking a file will fail if the file is opened only for append. To lock a file,844    /// open it with one of `.read(true)`, `.read(true).append(true)`, or `.write(true)`.845    ///846    /// [changes]: io#platform-specific-behavior847    ///848    /// [`lock`]: File::lock849    /// [`lock_shared`]: File::lock_shared850    /// [`try_lock`]: File::try_lock851    /// [`try_lock_shared`]: File::try_lock_shared852    /// [`unlock`]: File::unlock853    /// [`read`]: Read::read854    /// [`write`]: Write::write855    ///856    /// # Examples857    ///858    /// ```no_run859    /// use std::fs::File;860    ///861    /// fn main() -> std::io::Result<()> {862    ///     let f = File::create("foo.txt")?;863    ///     f.lock()?;864    ///     Ok(())865    /// }866    /// ```867    #[stable(feature = "file_lock", since = "1.89.0")]868    pub fn lock(&self) -> io::Result<()> {869        self.inner.lock()870    }871872    /// Acquire a shared (non-exclusive) lock on the file. Blocks until the lock can be acquired.873    ///874    /// This acquires a shared lock. More than one file handle to this file, in this or any other875    /// process, may hold a shared lock, but no *other* file handle may hold an exclusive lock at876    /// the same time.877    /// If this file handle/descriptor, or a clone of it, already holds a lock, the exact878    /// behavior is unspecified and platform dependent, including the possibility that it will879    /// deadlock. However, if this method returns, then a shared lock is held.880    ///881    /// This lock may be advisory or mandatory. This lock is meant to interact with [`lock`],882    /// [`try_lock`], [`lock_shared`], [`try_lock_shared`], and [`unlock`]. Its interactions with883    /// other methods, such as [`read`] and [`write`] are platform specific, and it may or may not884    /// cause non-lockholders to block.885    ///886    /// The lock will be released when this file (along with any other file descriptors/handles887    /// duplicated or inherited from it) is closed, or if the [`unlock`] method is called.888    ///889    /// # Platform-specific behavior890    ///891    /// This function currently corresponds to the `flock` function on Unix with the `LOCK_SH` flag,892    /// and the `LockFileEx` function on Windows. Note that, this893    /// [may change in the future][changes].894    ///895    /// On Windows, locking a file will fail if the file is opened only for append. To lock a file,896    /// open it with one of `.read(true)`, `.read(true).append(true)`, or `.write(true)`.897    ///898    /// [changes]: io#platform-specific-behavior899    ///900    /// [`lock`]: File::lock901    /// [`lock_shared`]: File::lock_shared902    /// [`try_lock`]: File::try_lock903    /// [`try_lock_shared`]: File::try_lock_shared904    /// [`unlock`]: File::unlock905    /// [`read`]: Read::read906    /// [`write`]: Write::write907    ///908    /// # Examples909    ///910    /// ```no_run911    /// use std::fs::File;912    ///913    /// fn main() -> std::io::Result<()> {914    ///     let f = File::open("foo.txt")?;915    ///     f.lock_shared()?;916    ///     Ok(())917    /// }918    /// ```919    #[stable(feature = "file_lock", since = "1.89.0")]920    pub fn lock_shared(&self) -> io::Result<()> {921        self.inner.lock_shared()922    }923924    /// Try to acquire an exclusive lock on the file.925    ///926    /// Returns `Err(TryLockError::WouldBlock)` if a different lock is already held on this file927    /// (via another handle/descriptor).928    ///929    /// This acquires an exclusive lock; no other file handle to this file, in this or any other930    /// process, may acquire another lock.931    ///932    /// This lock may be advisory or mandatory. This lock is meant to interact with [`lock`],933    /// [`try_lock`], [`lock_shared`], [`try_lock_shared`], and [`unlock`]. Its interactions with934    /// other methods, such as [`read`] and [`write`] are platform specific, and it may or may not935    /// cause non-lockholders to block.936    ///937    /// If this file handle/descriptor, or a clone of it, already holds a lock, the exact behavior938    /// is unspecified and platform dependent, including the possibility that it will deadlock.939    /// However, if this method returns `Ok(())`, then it has acquired an exclusive lock.940    ///941    /// If the file is not open for writing, it is unspecified whether this function returns an error.942    ///943    /// The lock will be released when this file (along with any other file descriptors/handles944    /// duplicated or inherited from it) is closed, or if the [`unlock`] method is called.945    ///946    /// # Platform-specific behavior947    ///948    /// This function currently corresponds to the `flock` function on Unix with the `LOCK_EX` and949    /// `LOCK_NB` flags, and the `LockFileEx` function on Windows with the `LOCKFILE_EXCLUSIVE_LOCK`950    /// and `LOCKFILE_FAIL_IMMEDIATELY` flags. Note that, this951    /// [may change in the future][changes].952    ///953    /// On Windows, locking a file will fail if the file is opened only for append. To lock a file,954    /// open it with one of `.read(true)`, `.read(true).append(true)`, or `.write(true)`.955    ///956    /// [changes]: io#platform-specific-behavior957    ///958    /// [`lock`]: File::lock959    /// [`lock_shared`]: File::lock_shared960    /// [`try_lock`]: File::try_lock961    /// [`try_lock_shared`]: File::try_lock_shared962    /// [`unlock`]: File::unlock963    /// [`read`]: Read::read964    /// [`write`]: Write::write965    ///966    /// # Examples967    ///968    /// ```no_run969    /// use std::fs::{File, TryLockError};970    ///971    /// fn main() -> std::io::Result<()> {972    ///     let f = File::create("foo.txt")?;973    ///     // Explicit handling of the WouldBlock error974    ///     match f.try_lock() {975    ///         Ok(_) => (),976    ///         Err(TryLockError::WouldBlock) => (), // Lock not acquired977    ///         Err(TryLockError::Error(err)) => return Err(err),978    ///     }979    ///     // Alternately, propagate the error as an io::Error980    ///     f.try_lock()?;981    ///     Ok(())982    /// }983    /// ```984    #[stable(feature = "file_lock", since = "1.89.0")]985    pub fn try_lock(&self) -> Result<(), TryLockError> {986        self.inner.try_lock()987    }988989    /// Try to acquire a shared (non-exclusive) lock on the file.990    ///991    /// Returns `Err(TryLockError::WouldBlock)` if a different lock is already held on this file992    /// (via another handle/descriptor).993    ///994    /// This acquires a shared lock; more than one file handle, in this or any other process, may995    /// hold a shared lock, but none may hold an exclusive lock at the same time.996    ///997    /// This lock may be advisory or mandatory. This lock is meant to interact with [`lock`],998    /// [`try_lock`], [`lock_shared`], [`try_lock_shared`], and [`unlock`]. Its interactions with999    /// other methods, such as [`read`] and [`write`] are platform specific, and it may or may not1000    /// cause non-lockholders to block.1001    ///1002    /// If this file handle, or a clone of it, already holds a lock, the exact behavior is1003    /// unspecified and platform dependent, including the possibility that it will deadlock.1004    /// However, if this method returns `Ok(())`, then it has acquired a shared lock.1005    ///1006    /// The lock will be released when this file (along with any other file descriptors/handles1007    /// duplicated or inherited from it) is closed, or if the [`unlock`] method is called.1008    ///1009    /// # Platform-specific behavior1010    ///1011    /// This function currently corresponds to the `flock` function on Unix with the `LOCK_SH` and1012    /// `LOCK_NB` flags, and the `LockFileEx` function on Windows with the1013    /// `LOCKFILE_FAIL_IMMEDIATELY` flag. Note that, this1014    /// [may change in the future][changes].1015    ///1016    /// On Windows, locking a file will fail if the file is opened only for append. To lock a file,1017    /// open it with one of `.read(true)`, `.read(true).append(true)`, or `.write(true)`.1018    ///1019    /// [changes]: io#platform-specific-behavior1020    ///1021    /// [`lock`]: File::lock1022    /// [`lock_shared`]: File::lock_shared1023    /// [`try_lock`]: File::try_lock1024    /// [`try_lock_shared`]: File::try_lock_shared1025    /// [`unlock`]: File::unlock1026    /// [`read`]: Read::read1027    /// [`write`]: Write::write1028    ///1029    /// # Examples1030    ///1031    /// ```no_run1032    /// use std::fs::{File, TryLockError};1033    ///1034    /// fn main() -> std::io::Result<()> {1035    ///     let f = File::open("foo.txt")?;1036    ///     // Explicit handling of the WouldBlock error1037    ///     match f.try_lock_shared() {1038    ///         Ok(_) => (),1039    ///         Err(TryLockError::WouldBlock) => (), // Lock not acquired1040    ///         Err(TryLockError::Error(err)) => return Err(err),1041    ///     }1042    ///     // Alternately, propagate the error as an io::Error1043    ///     f.try_lock_shared()?;1044    ///1045    ///     Ok(())1046    /// }1047    /// ```1048    #[stable(feature = "file_lock", since = "1.89.0")]1049    pub fn try_lock_shared(&self) -> Result<(), TryLockError> {1050        self.inner.try_lock_shared()1051    }10521053    /// Release all locks on the file.1054    ///1055    /// All locks are released when the file (along with any other file descriptors/handles1056    /// duplicated or inherited from it) is closed. This method allows releasing locks without1057    /// closing the file.1058    ///1059    /// If no lock is currently held via this file descriptor/handle, this method may return an1060    /// error, or may return successfully without taking any action.1061    ///1062    /// # Platform-specific behavior1063    ///1064    /// This function currently corresponds to the `flock` function on Unix with the `LOCK_UN` flag,1065    /// and the `UnlockFile` function on Windows. Note that, this1066    /// [may change in the future][changes].1067    ///1068    /// On Windows, locking a file will fail if the file is opened only for append. To lock a file,1069    /// open it with one of `.read(true)`, `.read(true).append(true)`, or `.write(true)`.1070    ///1071    /// [changes]: io#platform-specific-behavior1072    ///1073    /// # Examples1074    ///1075    /// ```no_run1076    /// use std::fs::File;1077    ///1078    /// fn main() -> std::io::Result<()> {1079    ///     let f = File::open("foo.txt")?;1080    ///     f.lock()?;1081    ///     f.unlock()?;1082    ///     Ok(())1083    /// }1084    /// ```1085    #[stable(feature = "file_lock", since = "1.89.0")]1086    pub fn unlock(&self) -> io::Result<()> {1087        self.inner.unlock()1088    }10891090    /// Truncates or extends the underlying file, updating the size of1091    /// this file to become `size`.1092    ///1093    /// If the `size` is less than the current file's size, then the file will1094    /// be shrunk. If it is greater than the current file's size, then the file1095    /// will be extended to `size` and have all of the intermediate data filled1096    /// in with 0s.1097    ///1098    /// The file's cursor isn't changed. In particular, if the cursor was at the1099    /// end and the file is shrunk using this operation, the cursor will now be1100    /// past the end.1101    ///1102    /// # Errors1103    ///1104    /// This function will return an error if the file is not opened for writing.1105    /// Also, [`std::io::ErrorKind::InvalidInput`](crate::io::ErrorKind::InvalidInput)1106    /// will be returned if the desired length would cause an overflow due to1107    /// the implementation specifics.1108    ///1109    /// # Examples1110    ///1111    /// ```no_run1112    /// use std::fs::File;1113    ///1114    /// fn main() -> std::io::Result<()> {1115    ///     let mut f = File::create("foo.txt")?;1116    ///     f.set_len(10)?;1117    ///     Ok(())1118    /// }1119    /// ```1120    ///1121    /// Note that this method alters the content of the underlying file, even1122    /// though it takes `&self` rather than `&mut self`.1123    #[stable(feature = "rust1", since = "1.0.0")]1124    pub fn set_len(&self, size: u64) -> io::Result<()> {1125        self.inner.truncate(size)1126    }11271128    /// Queries metadata about the underlying file.1129    ///1130    /// # Examples1131    ///1132    /// ```no_run1133    /// use std::fs::File;1134    ///1135    /// fn main() -> std::io::Result<()> {1136    ///     let mut f = File::open("foo.txt")?;1137    ///     let metadata = f.metadata()?;1138    ///     Ok(())1139    /// }1140    /// ```1141    #[stable(feature = "rust1", since = "1.0.0")]1142    pub fn metadata(&self) -> io::Result<Metadata> {1143        self.inner.file_attr().map(Metadata)1144    }11451146    /// Creates a new `File` instance that shares the same underlying file handle1147    /// as the existing `File` instance. Reads, writes, and seeks will affect1148    /// both `File` instances simultaneously.1149    ///1150    /// # Examples1151    ///1152    /// Creates two handles for a file named `foo.txt`:1153    ///1154    /// ```no_run1155    /// use std::fs::File;1156    ///1157    /// fn main() -> std::io::Result<()> {1158    ///     let mut file = File::open("foo.txt")?;1159    ///     let file_copy = file.try_clone()?;1160    ///     Ok(())1161    /// }1162    /// ```1163    ///1164    /// Assuming there’s a file named `foo.txt` with contents `abcdef\n`, create1165    /// two handles, seek one of them, and read the remaining bytes from the1166    /// other handle:1167    ///1168    /// ```no_run1169    /// use std::fs::File;1170    /// use std::io::SeekFrom;1171    /// use std::io::prelude::*;1172    ///1173    /// fn main() -> std::io::Result<()> {1174    ///     let mut file = File::open("foo.txt")?;1175    ///     let mut file_copy = file.try_clone()?;1176    ///1177    ///     file.seek(SeekFrom::Start(3))?;1178    ///1179    ///     let mut contents = vec![];1180    ///     file_copy.read_to_end(&mut contents)?;1181    ///     assert_eq!(contents, b"def\n");1182    ///     Ok(())1183    /// }1184    /// ```1185    #[stable(feature = "file_try_clone", since = "1.9.0")]1186    pub fn try_clone(&self) -> io::Result<File> {1187        Ok(File { inner: self.inner.duplicate()? })1188    }11891190    /// Changes the permissions on the underlying file.1191    ///1192    /// # Platform-specific behavior1193    ///1194    /// This function currently corresponds to the `fchmod` function on Unix and1195    /// the `SetFileInformationByHandle` function on Windows. Note that, this1196    /// [may change in the future][changes].1197    ///1198    /// [changes]: io#platform-specific-behavior1199    ///1200    /// # Errors1201    ///1202    /// This function will return an error if the user lacks permission change1203    /// attributes on the underlying file. It may also return an error in other1204    /// os-specific unspecified cases.1205    ///1206    /// # Examples1207    ///1208    /// ```no_run1209    /// fn main() -> std::io::Result<()> {1210    ///     use std::fs::File;1211    ///1212    ///     let file = File::open("foo.txt")?;1213    ///     let mut perms = file.metadata()?.permissions();1214    ///     perms.set_readonly(true);1215    ///     file.set_permissions(perms)?;1216    ///     Ok(())1217    /// }1218    /// ```1219    ///1220    /// Note that this method alters the permissions of the underlying file,1221    /// even though it takes `&self` rather than `&mut self`.1222    #[doc(alias = "fchmod", alias = "SetFileInformationByHandle")]1223    #[stable(feature = "set_permissions_atomic", since = "1.16.0")]1224    pub fn set_permissions(&self, perm: Permissions) -> io::Result<()> {1225        self.inner.set_permissions(perm.0)1226    }12271228    /// Changes the timestamps of the underlying file.1229    ///1230    /// # Platform-specific behavior1231    ///1232    /// This function currently corresponds to the `futimens` function on Unix (falling back to1233    /// `futimes` on macOS before 10.13) and the `SetFileTime` function on Windows. Note that this1234    /// [may change in the future][changes].1235    ///1236    /// On most platforms, including UNIX and Windows platforms, this function can also change the1237    /// timestamps of a directory. To get a `File` representing a directory in order to call1238    /// `set_times`, open the directory with `File::open` without attempting to obtain write1239    /// permission.1240    ///1241    /// [changes]: io#platform-specific-behavior1242    ///1243    /// # Errors1244    ///1245    /// This function will return an error if the user lacks permission to change timestamps on the1246    /// underlying file. It may also return an error in other os-specific unspecified cases.1247    ///1248    /// This function may return an error if the operating system lacks support to change one or1249    /// more of the timestamps set in the `FileTimes` structure.1250    ///1251    /// # Examples1252    ///1253    /// ```no_run1254    /// fn main() -> std::io::Result<()> {1255    ///     use std::fs::{self, File, FileTimes};1256    ///1257    ///     let src = fs::metadata("src")?;1258    ///     let dest = File::open("dest")?;1259    ///     let times = FileTimes::new()1260    ///         .set_accessed(src.accessed()?)1261    ///         .set_modified(src.modified()?);1262    ///     dest.set_times(times)?;1263    ///     Ok(())1264    /// }1265    /// ```1266    #[stable(feature = "file_set_times", since = "1.75.0")]1267    #[doc(alias = "futimens")]1268    #[doc(alias = "futimes")]1269    #[doc(alias = "SetFileTime")]1270    #[doc(alias = "filetime")]1271    pub fn set_times(&self, times: FileTimes) -> io::Result<()> {1272        self.inner.set_times(times.0)1273    }12741275    /// Changes the modification time of the underlying file.1276    ///1277    /// This is an alias for `set_times(FileTimes::new().set_modified(time))`.1278    #[stable(feature = "file_set_times", since = "1.75.0")]1279    #[inline]1280    pub fn set_modified(&self, time: SystemTime) -> io::Result<()> {1281        self.set_times(FileTimes::new().set_modified(time))1282    }1283}12841285// In addition to the `impl`s here, `File` also has `impl`s for1286// `AsFd`/`From<OwnedFd>`/`Into<OwnedFd>` and1287// `AsRawFd`/`IntoRawFd`/`FromRawFd`, on Unix and WASI, and1288// `AsHandle`/`From<OwnedHandle>`/`Into<OwnedHandle>` and1289// `AsRawHandle`/`IntoRawHandle`/`FromRawHandle` on Windows.12901291impl AsInner<fs_imp::File> for File {1292    #[inline]1293    fn as_inner(&self) -> &fs_imp::File {1294        &self.inner1295    }1296}1297impl FromInner<fs_imp::File> for File {1298    fn from_inner(f: fs_imp::File) -> File {1299        File { inner: f }1300    }1301}1302impl IntoInner<fs_imp::File> for File {1303    fn into_inner(self) -> fs_imp::File {1304        self.inner1305    }1306}13071308#[stable(feature = "rust1", since = "1.0.0")]1309impl fmt::Debug for File {1310    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {1311        self.inner.fmt(f)1312    }1313}13141315/// Indicates how much extra capacity is needed to read the rest of the file.1316fn buffer_capacity_required(mut file: &File) -> Option<usize> {1317    let size = file.metadata().map(|m| m.len()).ok()?;1318    let pos = file.stream_position().ok()?;1319    // Don't worry about `usize` overflow because reading will fail regardless1320    // in that case.1321    Some(size.saturating_sub(pos) as usize)1322}13231324#[stable(feature = "rust1", since = "1.0.0")]1325impl Read for &File {1326    /// Reads some bytes from the file.1327    ///1328    /// See [`Read::read`] docs for more info.1329    ///1330    /// # Platform-specific behavior1331    ///1332    /// This function currently corresponds to the `read` function on Unix and1333    /// the `NtReadFile` function on Windows. Note that this [may change in1334    /// the future][changes].1335    ///1336    /// [changes]: io#platform-specific-behavior1337    #[inline]1338    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {1339        self.inner.read(buf)1340    }13411342    /// Like `read`, except that it reads into a slice of buffers.1343    ///1344    /// See [`Read::read_vectored`] docs for more info.1345    ///1346    /// # Platform-specific behavior1347    ///1348    /// This function currently corresponds to the `readv` function on Unix and1349    /// falls back to the `read` implementation on Windows. Note that this1350    /// [may change in the future][changes].1351    ///1352    /// [changes]: io#platform-specific-behavior1353    #[inline]1354    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {1355        self.inner.read_vectored(bufs)1356    }13571358    #[inline]1359    fn read_buf(&mut self, cursor: BorrowedCursor<'_, u8>) -> io::Result<()> {1360        self.inner.read_buf(cursor)1361    }13621363    /// Determines if `File` has an efficient `read_vectored` implementation.1364    ///1365    /// See [`Read::is_read_vectored`] docs for more info.1366    ///1367    /// # Platform-specific behavior1368    ///1369    /// This function currently returns `true` on Unix and `false` on Windows.1370    /// Note that this [may change in the future][changes].1371    ///1372    /// [changes]: io#platform-specific-behavior1373    #[inline]1374    fn is_read_vectored(&self) -> bool {1375        self.inner.is_read_vectored()1376    }13771378    // Reserves space in the buffer based on the file size when available.1379    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {1380        let size = buffer_capacity_required(self);1381        buf.try_reserve(size.unwrap_or(0))?;1382        io::default_read_to_end(self, buf, size)1383    }13841385    // Reserves space in the buffer based on the file size when available.1386    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {1387        let size = buffer_capacity_required(self);1388        buf.try_reserve(size.unwrap_or(0))?;1389        io::default_read_to_string(self, buf, size)1390    }1391}1392#[stable(feature = "rust1", since = "1.0.0")]1393impl Write for &File {1394    /// Writes some bytes to the file.1395    ///1396    /// See [`Write::write`] docs for more info.1397    ///1398    /// # Platform-specific behavior1399    ///1400    /// This function currently corresponds to the `write` function on Unix and1401    /// the `NtWriteFile` function on Windows. Note that this [may change in1402    /// the future][changes].1403    ///1404    /// [changes]: io#platform-specific-behavior1405    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {1406        self.inner.write(buf)1407    }14081409    /// Like `write`, except that it writes into a slice of buffers.1410    ///1411    /// See [`Write::write_vectored`] docs for more info.1412    ///1413    /// # Platform-specific behavior1414    ///1415    /// This function currently corresponds to the `writev` function on Unix1416    /// and falls back to the `write` implementation on Windows. Note that this1417    /// [may change in the future][changes].1418    ///1419    /// [changes]: io#platform-specific-behavior1420    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {1421        self.inner.write_vectored(bufs)1422    }14231424    /// Determines if `File` has an efficient `write_vectored` implementation.1425    ///1426    /// See [`Write::is_write_vectored`] docs for more info.1427    ///1428    /// # Platform-specific behavior1429    ///1430    /// This function currently returns `true` on Unix and `false` on Windows.1431    /// Note that this [may change in the future][changes].1432    ///1433    /// [changes]: io#platform-specific-behavior1434    #[inline]1435    fn is_write_vectored(&self) -> bool {1436        self.inner.is_write_vectored()1437    }14381439    /// Flushes the file, ensuring that all intermediately buffered contents1440    /// reach their destination.1441    ///1442    /// See [`Write::flush`] docs for more info.1443    ///1444    /// # Platform-specific behavior1445    ///1446    /// Since a `File` structure doesn't contain any buffers, this function is1447    /// currently a no-op on Unix and Windows. Note that this [may change in1448    /// the future][changes].1449    ///1450    /// [changes]: io#platform-specific-behavior1451    #[inline]1452    fn flush(&mut self) -> io::Result<()> {1453        self.inner.flush()1454    }1455}1456#[stable(feature = "rust1", since = "1.0.0")]1457impl Seek for &File {1458    /// Seek to an offset, in bytes in a file.1459    ///1460    /// See [`Seek::seek`] docs for more info.1461    ///1462    /// # Platform-specific behavior1463    ///1464    /// This function currently corresponds to the `lseek64` function on Unix1465    /// and the `SetFilePointerEx` function on Windows. Note that this [may1466    /// change in the future][changes].1467    ///1468    /// [changes]: io#platform-specific-behavior1469    fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {1470        self.inner.seek(pos)1471    }14721473    /// Returns the length of this file (in bytes).1474    ///1475    /// See [`Seek::stream_len`] docs for more info.1476    ///1477    /// # Platform-specific behavior1478    ///1479    /// This function currently corresponds to the `statx` function on Linux1480    /// (with fallbacks) and the `GetFileSizeEx` function on Windows. Note that1481    /// this [may change in the future][changes].1482    ///1483    /// [changes]: io#platform-specific-behavior1484    fn stream_len(&mut self) -> io::Result<u64> {1485        if let Some(result) = self.inner.size() {1486            return result;1487        }1488        io::stream_len_default(self)1489    }14901491    fn stream_position(&mut self) -> io::Result<u64> {1492        self.inner.tell()1493    }1494}14951496#[stable(feature = "rust1", since = "1.0.0")]1497impl Read for File {1498    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {1499        (&*self).read(buf)1500    }1501    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {1502        (&*self).read_vectored(bufs)1503    }1504    fn read_buf(&mut self, cursor: BorrowedCursor<'_, u8>) -> io::Result<()> {1505        (&*self).read_buf(cursor)1506    }1507    #[inline]1508    fn is_read_vectored(&self) -> bool {1509        (&self).is_read_vectored()1510    }1511    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {1512        (&*self).read_to_end(buf)1513    }1514    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {1515        (&*self).read_to_string(buf)1516    }1517}1518#[stable(feature = "rust1", since = "1.0.0")]1519impl Write for File {1520    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {1521        (&*self).write(buf)1522    }1523    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {1524        (&*self).write_vectored(bufs)1525    }1526    #[inline]1527    fn is_write_vectored(&self) -> bool {1528        (&self).is_write_vectored()1529    }1530    #[inline]1531    fn flush(&mut self) -> io::Result<()> {1532        (&*self).flush()1533    }1534}1535#[stable(feature = "rust1", since = "1.0.0")]1536impl Seek for File {1537    fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {1538        (&*self).seek(pos)1539    }1540    fn stream_len(&mut self) -> io::Result<u64> {1541        (&*self).stream_len()1542    }1543    fn stream_position(&mut self) -> io::Result<u64> {1544        (&*self).stream_position()1545    }1546}1547#[doc(hidden)]1548#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]1549impl crate::io::IoHandle for File {}15501551impl Dir {1552    /// Attempts to open a directory at `path` in read-only mode.1553    ///1554    /// This function opens a directory. To open a file instead, see [`File::open`].1555    ///1556    /// # Errors1557    ///1558    /// This function will return an error if `path` does not point to an existing directory.1559    /// Other errors may also be returned according to [`OpenOptions::open`].1560    ///1561    /// # Examples1562    ///1563    /// ```no_run1564    /// #![feature(dirfd)]1565    /// use std::{fs::Dir, io};1566    ///1567    /// fn main() -> std::io::Result<()> {1568    ///     let dir = Dir::open("foo")?;1569    ///     let mut f = dir.open_file("bar.txt")?;1570    ///     let contents = io::read_to_string(f)?;1571    ///     assert_eq!(contents, "Hello, world!");1572    ///     Ok(())1573    /// }1574    /// ```1575    #[unstable(feature = "dirfd", issue = "120426")]1576    pub fn open<P: AsRef<Path>>(path: P) -> io::Result<Self> {1577        fs_imp::Dir::open(path.as_ref(), &OpenOptions::new().read(true).0)1578            .map(|inner| Self { inner })1579    }15801581    /// Queries metadata about the underlying directory.1582    ///1583    /// # Examples1584    ///1585    /// ```no_run1586    /// #![feature(dirfd)]1587    /// use std::fs::Dir;1588    ///1589    /// fn main() -> std::io::Result<()> {1590    ///     let dir = Dir::open("foo")?;1591    ///     let metadata = dir.metadata()?;1592    ///     Ok(())1593    /// }1594    /// ```1595    #[unstable(feature = "dirfd", issue = "120426")]1596    pub fn metadata(&self) -> io::Result<Metadata> {1597        self.inner.metadata().map(Metadata)1598    }15991600    /// Attempts to open a file in read-only mode relative to this directory.1601    ///1602    /// This function interprets `path` relative to the directory provided by `self`. To open a file1603    /// relative to the current working directory, or at an absolute path, see [`File::open`].1604    ///1605    /// # Errors1606    ///1607    /// This function will return an error if `path` does not point to an existing file.1608    /// Other errors may also be returned according to [`OpenOptions::open`].1609    ///1610    /// # Examples1611    ///1612    /// ```no_run1613    /// #![feature(dirfd)]1614    /// use std::{fs::Dir, io};1615    ///1616    /// fn main() -> std::io::Result<()> {1617    ///     let dir = Dir::open("foo")?;1618    ///     let mut f = dir.open_file("bar.txt")?;1619    ///     let contents = io::read_to_string(f)?;1620    ///     assert_eq!(contents, "Hello, world!");1621    ///     Ok(())1622    /// }1623    /// ```1624    #[unstable(feature = "dirfd", issue = "120426")]1625    pub fn open_file<P: AsRef<Path>>(&self, path: P) -> io::Result<File> {1626        self.inner1627            .open_file(path.as_ref(), &OpenOptions::new().read(true).0)1628            .map(|f| File { inner: f })1629    }16301631    /// Attempts to open a file according to `opts` relative to this directory.1632    ///1633    /// This function interprets `path` relative to the directory provided by `self`. To open a file1634    /// relative to the current working directory, or at an absolute path, see [`File::open`].1635    ///1636    /// # Errors1637    ///1638    /// This function will return an error if `path` does not point to an existing file.1639    /// Other errors may also be returned according to [`OpenOptions::open`].1640    ///1641    /// # Examples1642    ///1643    /// ```no_run1644    /// #![feature(dirfd)]1645    /// use std::{fs::{Dir, OpenOptions}, io::{self, Write}};1646    ///1647    /// fn main() -> io::Result<()> {1648    ///     let dir = Dir::open("foo")?;1649    ///     let mut opts = OpenOptions::new();1650    ///     opts.read(true).write(true);1651    ///     let mut f = dir.open_file_with("bar.txt", &opts)?;1652    ///     f.write_all(b"Hello, world!")?;1653    ///     let contents = io::read_to_string(f)?;1654    ///     assert_eq!(contents, "Hello, world!");1655    ///     Ok(())1656    /// }1657    /// ```1658    #[unstable(feature = "dirfd", issue = "120426")]1659    pub fn open_file_with<P: AsRef<Path>>(&self, path: P, opts: &OpenOptions) -> io::Result<File> {1660        self.inner.open_file(path.as_ref(), &opts.0).map(|f| File { inner: f })1661    }16621663    /// Attempts to remove a file relative to this directory.1664    ///1665    /// This function interprets `path` relative to the directory provided by `self`. To remove a file1666    /// relative to the current working directory, or at an absolute path, see [`fs::remove_file`][remove_file].1667    ///1668    /// # Errors1669    ///1670    /// This function will return an error if `path` does not point to an existing file.1671    /// Other errors may also be returned according to [`OpenOptions::open`].1672    ///1673    /// # Examples1674    ///1675    /// ```no_run1676    /// #![feature(dirfd)]1677    /// use std::fs::Dir;1678    ///1679    /// fn main() -> std::io::Result<()> {1680    ///     let dir = Dir::open("foo")?;1681    ///     dir.remove_file("bar.txt")?;1682    ///     Ok(())1683    /// }1684    /// ```1685    #[unstable(feature = "dirfd", issue = "120426")]1686    pub fn remove_file<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {1687        self.inner.remove_file(path.as_ref())1688    }16891690    /// Attempts to rename a file or directory relative to this directory to a new name, replacing1691    /// the destination file if present.1692    ///1693    /// This function interprets `from` relative to the directory provided by `self` and `to` relative to the directory1694    /// provided by `to_dir`. To rename a file relative to the current working directory, or at an absolute path, see [`fs::rename`][rename].1695    ///1696    /// # Errors1697    ///1698    /// This function will return an error if `from` does not point to an existing file or directory.1699    /// Other errors may also be returned according to [`OpenOptions::open`].1700    ///1701    /// # Examples1702    ///1703    /// ```no_run1704    /// #![feature(dirfd)]1705    /// use std::fs::Dir;1706    ///1707    /// fn main() -> std::io::Result<()> {1708    ///     let dir = Dir::open("foo")?;1709    ///     dir.rename("bar.txt", &dir, "quux.txt")?;1710    ///     Ok(())1711    /// }1712    /// ```1713    #[unstable(feature = "dirfd", issue = "120426")]1714    pub fn rename<P: AsRef<Path>, Q: AsRef<Path>>(1715        &self,1716        from: P,1717        to_dir: &Self,1718        to: Q,1719    ) -> io::Result<()> {1720        self.inner.rename(from.as_ref(), &to_dir.inner, to.as_ref())1721    }1722}17231724impl AsInner<fs_imp::Dir> for Dir {1725    #[inline]1726    fn as_inner(&self) -> &fs_imp::Dir {1727        &self.inner1728    }1729}1730impl FromInner<fs_imp::Dir> for Dir {1731    fn from_inner(f: fs_imp::Dir) -> Dir {1732        Dir { inner: f }1733    }1734}1735impl IntoInner<fs_imp::Dir> for Dir {1736    fn into_inner(self) -> fs_imp::Dir {1737        self.inner1738    }1739}17401741#[unstable(feature = "dirfd", issue = "120426")]1742impl fmt::Debug for Dir {1743    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {1744        self.inner.fmt(f)1745    }1746}17471748impl OpenOptions {1749    /// Creates a blank new set of options ready for configuration.1750    ///1751    /// All options are initially set to `false`.1752    ///1753    /// # Examples1754    ///1755    /// ```no_run1756    /// use std::fs::OpenOptions;1757    ///1758    /// let mut options = OpenOptions::new();1759    /// let file = options.read(true).open("foo.txt");1760    /// ```1761    #[cfg_attr(not(test), rustc_diagnostic_item = "open_options_new")]1762    #[stable(feature = "rust1", since = "1.0.0")]1763    #[must_use]1764    pub fn new() -> Self {1765        OpenOptions(fs_imp::OpenOptions::new())1766    }17671768    /// Sets the option for read access.1769    ///1770    /// This option, when true, will indicate that the file should be1771    /// `read`-able if opened.1772    ///1773    /// # Examples1774    ///1775    /// ```no_run1776    /// use std::fs::OpenOptions;1777    ///1778    /// let file = OpenOptions::new().read(true).open("foo.txt");1779    /// ```1780    #[stable(feature = "rust1", since = "1.0.0")]1781    pub fn read(&mut self, read: bool) -> &mut Self {1782        self.0.read(read);1783        self1784    }17851786    /// Sets the option for write access.1787    ///1788    /// This option, when true, will indicate that the file should be1789    /// `write`-able if opened.1790    ///1791    /// If the file already exists, any write calls on it will overwrite its1792    /// contents, without truncating it.1793    ///1794    /// # Examples1795    ///1796    /// ```no_run1797    /// use std::fs::OpenOptions;1798    ///1799    /// let file = OpenOptions::new().write(true).open("foo.txt");1800    /// ```1801    #[stable(feature = "rust1", since = "1.0.0")]1802    pub fn write(&mut self, write: bool) -> &mut Self {1803        self.0.write(write);1804        self1805    }18061807    /// Sets the option for the append mode.1808    ///1809    /// This option, when true, means that writes will append to a file instead1810    /// of overwriting previous contents.1811    /// Note that setting `.write(true).append(true)` has the same effect as1812    /// setting only `.append(true)`.1813    ///1814    /// Append mode guarantees that writes will be positioned at the current end of file,1815    /// even when there are other processes or threads appending to the same file. This is1816    /// unlike <code>[seek]\([SeekFrom]::[End]\(0))</code> followed by `write()`, which1817    /// has a race between seeking and writing during which another writer can write, with1818    /// our `write()` overwriting their data.1819    ///1820    /// Keep in mind that this does not necessarily guarantee that data appended by1821    /// different processes or threads does not interleave. The amount of data accepted a1822    /// single `write()` call depends on the operating system and file system. A1823    /// successful `write()` is allowed to write only part of the given data, so even if1824    /// you're careful to provide the whole message in a single call to `write()`, there1825    /// is no guarantee that it will be written out in full. If you rely on the filesystem1826    /// accepting the message in a single write, make sure that all data that belongs1827    /// together is written in one operation. This can be done by concatenating strings1828    /// before passing them to [`write()`].1829    ///1830    /// If a file is opened with both read and append access, beware that after1831    /// opening, and after every write, the position for reading may be set at the1832    /// end of the file. So, before writing, save the current position (using1833    /// <code>[Seek]::[stream_position]</code>), and restore it before the next read.1834    ///1835    /// ## Note1836    ///1837    /// This function doesn't create the file if it doesn't exist. Use the1838    /// [`OpenOptions::create`] method to do so.1839    ///1840    /// [`write()`]: Write::write "io::Write::write"1841    /// [`flush()`]: Write::flush "io::Write::flush"1842    /// [stream_position]: Seek::stream_position "io::Seek::stream_position"1843    /// [seek]: Seek::seek "io::Seek::seek"1844    /// [Current]: SeekFrom::Current "io::SeekFrom::Current"1845    /// [End]: SeekFrom::End "io::SeekFrom::End"1846    ///1847    /// # Examples1848    ///1849    /// ```no_run1850    /// use std::fs::OpenOptions;1851    ///1852    /// let file = OpenOptions::new().append(true).open("foo.txt");1853    /// ```1854    #[stable(feature = "rust1", since = "1.0.0")]1855    pub fn append(&mut self, append: bool) -> &mut Self {1856        self.0.append(append);1857        self1858    }18591860    /// Sets the option for truncating a previous file.1861    ///1862    /// If a file is successfully opened with this option set to true, it will truncate1863    /// the file to 0 length if it already exists.1864    ///1865    /// The file must be opened with write access for truncate to work.1866    ///1867    /// # Examples1868    ///1869    /// ```no_run1870    /// use std::fs::OpenOptions;1871    ///1872    /// let file = OpenOptions::new().write(true).truncate(true).open("foo.txt");1873    /// ```1874    #[stable(feature = "rust1", since = "1.0.0")]1875    pub fn truncate(&mut self, truncate: bool) -> &mut Self {1876        self.0.truncate(truncate);1877        self1878    }18791880    /// Sets the option to create a new file, or open it if it already exists.1881    ///1882    /// In order for the file to be created, [`OpenOptions::write`] or1883    /// [`OpenOptions::append`] access must be used.1884    ///1885    /// See also [`std::fs::write()`][self::write] for a simple function to1886    /// create a file with some given data.1887    ///1888    /// # Errors1889    ///1890    /// If `.create(true)` is set without `.write(true)` or `.append(true)`,1891    /// calling [`open`](Self::open) will fail with [`InvalidInput`](io::ErrorKind::InvalidInput) error.1892    /// # Examples1893    ///1894    /// ```no_run1895    /// use std::fs::OpenOptions;1896    ///1897    /// let file = OpenOptions::new().write(true).create(true).open("foo.txt");1898    /// ```1899    #[stable(feature = "rust1", since = "1.0.0")]1900    pub fn create(&mut self, create: bool) -> &mut Self {1901        self.0.create(create);1902        self1903    }19041905    /// Sets the option to create a new file, failing if it already exists.1906    ///1907    /// No file is allowed to exist at the target location, also no (dangling) symlink. In this1908    /// way, if the call succeeds, the file returned is guaranteed to be new.1909    /// If a file exists at the target location, creating a new file will fail with [`AlreadyExists`]1910    /// or another error based on the situation. See [`OpenOptions::open`] for a1911    /// non-exhaustive list of likely errors.1912    ///1913    /// This option is useful because it is atomic. Otherwise between checking1914    /// whether a file exists and creating a new one, the file may have been1915    /// created by another process (a [TOCTOU] race condition / attack).1916    ///1917    /// If `.create_new(true)` is set, [`.create()`] and [`.truncate()`] are1918    /// ignored.1919    ///1920    /// The file must be opened with write or append access in order to create1921    /// a new file.1922    ///1923    /// [`.create()`]: OpenOptions::create1924    /// [`.truncate()`]: OpenOptions::truncate1925    /// [`AlreadyExists`]: io::ErrorKind::AlreadyExists1926    /// [TOCTOU]: self#time-of-check-to-time-of-use-toctou1927    ///1928    /// # Examples1929    ///1930    /// ```no_run1931    /// use std::fs::OpenOptions;1932    ///1933    /// let file = OpenOptions::new().write(true)1934    ///                              .create_new(true)1935    ///                              .open("foo.txt");1936    /// ```1937    #[stable(feature = "expand_open_options2", since = "1.9.0")]1938    pub fn create_new(&mut self, create_new: bool) -> &mut Self {1939        self.0.create_new(create_new);1940        self1941    }19421943    /// Opens a file at `path` with the options specified by `self`.1944    ///1945    /// # Errors1946    ///1947    /// This function will return an error under a number of different1948    /// circumstances. Some of these error conditions are listed here, together1949    /// with their [`io::ErrorKind`]. The mapping to [`io::ErrorKind`]s is not1950    /// part of the compatibility contract of the function.1951    ///1952    /// * [`NotFound`]: The specified file does not exist and neither `create`1953    ///   or `create_new` is set.1954    /// * [`NotFound`]: One of the directory components of the file path does1955    ///   not exist.1956    /// * [`PermissionDenied`]: The user lacks permission to get the specified1957    ///   access rights for the file.1958    /// * [`PermissionDenied`]: The user lacks permission to open one of the1959    ///   directory components of the specified path.1960    /// * [`AlreadyExists`]: `create_new` was specified and the file already1961    ///   exists.1962    /// * [`InvalidInput`]: Invalid combinations of open options (truncate1963    ///   without write access, create without write or append access,1964    ///   no access mode set, etc.).1965    ///1966    /// The following errors don't match any existing [`io::ErrorKind`] at the moment:1967    /// * One of the directory components of the specified file path1968    ///   was not, in fact, a directory.1969    /// * Filesystem-level errors: full disk, write permission1970    ///   requested on a read-only file system, exceeded disk quota, too many1971    ///   open files, too long filename, too many symbolic links in the1972    ///   specified path (Unix-like systems only), etc.1973    ///1974    /// # Examples1975    ///1976    /// ```no_run1977    /// use std::fs::OpenOptions;1978    ///1979    /// let file = OpenOptions::new().read(true).open("foo.txt");1980    /// ```1981    ///1982    /// [`AlreadyExists`]: io::ErrorKind::AlreadyExists1983    /// [`InvalidInput`]: io::ErrorKind::InvalidInput1984    /// [`NotFound`]: io::ErrorKind::NotFound1985    /// [`PermissionDenied`]: io::ErrorKind::PermissionDenied1986    #[stable(feature = "rust1", since = "1.0.0")]1987    pub fn open<P: AsRef<Path>>(&self, path: P) -> io::Result<File> {1988        self._open(path.as_ref())1989    }19901991    fn _open(&self, path: &Path) -> io::Result<File> {1992        fs_imp::File::open(path, &self.0).map(|inner| File { inner })1993    }1994}19951996impl AsInner<fs_imp::OpenOptions> for OpenOptions {1997    #[inline]1998    fn as_inner(&self) -> &fs_imp::OpenOptions {1999        &self.02000    }

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.