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};5152pub(crate) mod dirs;5354#[unstable(feature = "fs_home_dirs", issue = "162082")]55pub use self::dirs::HomeDirs;56#[unstable(feature = "fs_media_dirs", issue = "162083")]57pub use self::dirs::MediaDirs;5859/// An object providing access to an open file on the filesystem.60///61/// An instance of a `File` can be read and/or written depending on what options62/// it was opened with. Files also implement [`Seek`] to alter the logical cursor63/// that the file contains internally.64///65/// Files are automatically closed when they go out of scope. Errors detected66/// on closing are ignored by the implementation of `Drop`. Use the method67/// [`sync_all`] if these errors must be manually handled.68///69/// `File` does not buffer reads and writes. For efficiency, consider wrapping the70/// file in a [`BufReader`] or [`BufWriter`] when performing many small [`read`]71/// or [`write`] calls, unless unbuffered reads and writes are required.72///73/// # Examples74///75/// Creates a new file and write bytes to it (you can also use [`write`]):76///77/// ```no_run78/// use std::fs::File;79/// use std::io::prelude::*;80///81/// fn main() -> std::io::Result<()> {82/// let mut file = File::create("foo.txt")?;83/// file.write_all(b"Hello, world!")?;84/// Ok(())85/// }86/// ```87///88/// Reads the contents of a file into a [`String`] (you can also use [`read`]):89///90/// ```no_run91/// use std::fs::File;92/// use std::io::prelude::*;93///94/// fn main() -> std::io::Result<()> {95/// let mut file = File::open("foo.txt")?;96/// let mut contents = String::new();97/// file.read_to_string(&mut contents)?;98/// assert_eq!(contents, "Hello, world!");99/// Ok(())100/// }101/// ```102///103/// Using a buffered [`Read`]er:104///105/// ```no_run106/// use std::fs::File;107/// use std::io::BufReader;108/// use std::io::prelude::*;109///110/// fn main() -> std::io::Result<()> {111/// let file = File::open("foo.txt")?;112/// let mut buf_reader = BufReader::new(file);113/// let mut contents = String::new();114/// buf_reader.read_to_string(&mut contents)?;115/// assert_eq!(contents, "Hello, world!");116/// Ok(())117/// }118/// ```119///120/// Note that, although read and write methods require a `&mut File`, because121/// of the interfaces for [`Read`] and [`Write`], the holder of a `&File` can122/// still modify the file, either through methods that take `&File` or by123/// retrieving the underlying OS object and modifying the file that way.124/// Additionally, many operating systems allow concurrent modification of files125/// by different processes. Avoid assuming that holding a `&File` means that the126/// file will not change.127///128/// # Platform-specific behavior129///130/// On Windows, the implementation of [`Read`] and [`Write`] traits for `File`131/// perform synchronous I/O operations. Therefore the underlying file must not132/// have been opened for asynchronous I/O (e.g. by using `FILE_FLAG_OVERLAPPED`).133///134/// [`BufReader`]: io::BufReader135/// [`BufWriter`]: io::BufWriter136/// [`sync_all`]: File::sync_all137/// [`write`]: File::write138/// [`read`]: File::read139#[stable(feature = "rust1", since = "1.0.0")]140#[cfg_attr(not(test), rustc_diagnostic_item = "File")]141#[diagnostic::on_move(note = "you can use `File::try_clone` to duplicate a `File` instance")]142pub struct File {143 inner: fs_imp::File,144}145146/// An enumeration of possible errors which can occur while trying to acquire a lock147/// from the [`try_lock`] method and [`try_lock_shared`] method on a [`File`].148///149/// [`try_lock`]: File::try_lock150/// [`try_lock_shared`]: File::try_lock_shared151#[stable(feature = "file_lock", since = "1.89.0")]152pub enum TryLockError {153 /// The lock could not be acquired due to an I/O error on the file. The standard library will154 /// not return an [`ErrorKind::WouldBlock`] error inside [`TryLockError::Error`]155 ///156 /// [`ErrorKind::WouldBlock`]: io::ErrorKind::WouldBlock157 Error(io::Error),158 /// The lock could not be acquired at this time because it is held by another handle/process.159 WouldBlock,160}161162/// An object providing access to a directory on the filesystem.163///164/// Directories are automatically closed when they go out of scope. Errors detected165/// on closing are ignored by the implementation of `Drop`.166///167/// # Platform-specific behavior168///169/// On supported systems (including Windows and some UNIX-based OSes), this function acquires a170/// handle/file descriptor for the directory. This allows functions like [`Dir::open_file`] to171/// avoid [TOCTOU] errors when the directory itself is being moved.172///173/// On other systems, it stores an absolute path (see [`canonicalize()`]). In the latter case, no174/// [TOCTOU] guarantees are made.175///176/// # Examples177///178/// Opens a directory and then a file inside it.179///180/// ```no_run181/// #![feature(dirfd)]182/// use std::{fs::Dir, io};183///184/// fn main() -> std::io::Result<()> {185/// let dir = Dir::open("foo")?;186/// let mut file = dir.open_file("bar.txt")?;187/// let contents = io::read_to_string(file)?;188/// assert_eq!(contents, "Hello, world!");189/// Ok(())190/// }191/// ```192///193/// [TOCTOU]: self#time-of-check-to-time-of-use-toctou194#[unstable(feature = "dirfd", issue = "120426")]195#[cfg_attr(not(test), rustc_diagnostic_item = "FsDir")]196pub struct Dir {197 inner: fs_imp::Dir,198}199200/// Metadata information about a file.201///202/// This structure is returned from the [`metadata`] or203/// [`symlink_metadata`] function or method and represents known204/// metadata about a file such as its permissions, size, modification205/// times, etc.206#[stable(feature = "rust1", since = "1.0.0")]207#[derive(Clone)]208#[cfg_attr(not(test), rustc_diagnostic_item = "FsMetadata")]209pub struct Metadata(fs_imp::FileAttr);210211/// Iterator over the entries in a directory.212///213/// This iterator is returned from the [`read_dir`] function of this module and214/// will yield instances of <code>[io::Result]<[DirEntry]></code>. Through a [`DirEntry`]215/// information like the entry's path and possibly other metadata can be216/// learned.217///218/// The order in which this iterator returns entries is platform and filesystem219/// dependent.220///221/// # Errors222/// This [`io::Result`] will be an [`Err`] if an error occurred while fetching223/// the next entry from the OS.224#[stable(feature = "rust1", since = "1.0.0")]225#[derive(Debug)]226#[cfg_attr(not(test), rustc_diagnostic_item = "FsReadDir")]227pub struct ReadDir(fs_imp::ReadDir);228229/// Entries returned by the [`ReadDir`] iterator.230///231/// An instance of `DirEntry` represents an entry inside of a directory on the232/// filesystem. Each entry can be inspected via methods to learn about the full233/// path or possibly other metadata through per-platform extension traits.234///235/// # Platform-specific behavior236///237/// On Unix, the `DirEntry` struct contains an internal reference to the open238/// directory. Holding `DirEntry` objects will consume a file handle even239/// after the `ReadDir` iterator is dropped.240///241/// Note that this [may change in the future][changes].242///243/// [changes]: io#platform-specific-behavior244#[stable(feature = "rust1", since = "1.0.0")]245#[cfg_attr(not(test), rustc_diagnostic_item = "FsDirEntry")]246pub struct DirEntry(fs_imp::DirEntry);247248/// Options and flags which can be used to configure how a file is opened.249///250/// This builder exposes the ability to configure how a [`File`] is opened and251/// what operations are permitted on the open file. The [`File::open`] and252/// [`File::create`] methods are aliases for commonly used options using this253/// builder.254///255/// Generally speaking, when using `OpenOptions`, you'll first call256/// [`OpenOptions::new`], then chain calls to methods to set each option, then257/// call [`OpenOptions::open`], passing the path of the file you're trying to258/// open. This will give you a [`io::Result`] with a [`File`] inside that you259/// can further operate on.260///261/// # Examples262///263/// Opening a file to read:264///265/// ```no_run266/// use std::fs::OpenOptions;267///268/// let file = OpenOptions::new().read(true).open("foo.txt");269/// ```270///271/// Opening a file for both reading and writing, as well as creating it if it272/// doesn't exist:273///274/// ```no_run275/// use std::fs::OpenOptions;276///277/// let file = OpenOptions::new()278/// .read(true)279/// .write(true)280/// .create(true)281/// .open("foo.txt");282/// ```283#[derive(Clone, Debug)]284#[stable(feature = "rust1", since = "1.0.0")]285#[cfg_attr(not(test), rustc_diagnostic_item = "FsOpenOptions")]286pub struct OpenOptions(fs_imp::OpenOptions);287288/// Representation of the various timestamps on a file.289#[derive(Copy, Clone, Debug, Default)]290#[stable(feature = "file_set_times", since = "1.75.0")]291#[must_use = "must be applied to a file via `File::set_times` to have any effect"]292pub struct FileTimes(fs_imp::FileTimes);293294/// Representation of the various permissions on a file.295///296/// This module only currently provides one bit of information,297/// [`Permissions::readonly`], which is exposed on all currently supported298/// platforms. Unix-specific functionality, such as mode bits, is available299/// through the [`PermissionsExt`] trait.300///301/// [`PermissionsExt`]: crate::os::unix::fs::PermissionsExt302#[derive(Clone, PartialEq, Eq, Debug)]303#[stable(feature = "rust1", since = "1.0.0")]304#[cfg_attr(not(test), rustc_diagnostic_item = "FsPermissions")]305pub struct Permissions(fs_imp::FilePermissions);306307/// A structure representing a type of file with accessors for each file type.308/// It is returned by [`Metadata::file_type`] method.309#[stable(feature = "file_type", since = "1.1.0")]310#[derive(Copy, Clone, PartialEq, Eq, Hash)]311#[cfg_attr(not(test), rustc_diagnostic_item = "FileType")]312pub struct FileType(fs_imp::FileType);313314/// A builder used to create directories in various manners.315///316/// This builder also supports platform-specific options.317#[stable(feature = "dir_builder", since = "1.6.0")]318#[cfg_attr(not(test), rustc_diagnostic_item = "DirBuilder")]319#[derive(Debug)]320pub struct DirBuilder {321 inner: fs_imp::DirBuilder,322 recursive: bool,323}324325/// Reads the entire contents of a file into a bytes vector.326///327/// This is a convenience function for using [`File::open`] and [`read_to_end`]328/// with fewer imports and without an intermediate variable.329///330/// [`read_to_end`]: Read::read_to_end331///332/// # Errors333///334/// This function will return an error if `path` does not already exist.335/// Other errors may also be returned according to [`OpenOptions::open`].336///337/// While reading from the file, this function handles [`io::ErrorKind::Interrupted`]338/// with automatic retries. See [io::Read] documentation for details.339///340/// # Examples341///342/// ```no_run343/// use std::fs;344///345/// fn main() -> Result<(), Box<dyn std::error::Error + 'static>> {346/// let data: Vec<u8> = fs::read("image.jpg")?;347/// assert_eq!(data[0..3], [0xFF, 0xD8, 0xFF]);348/// Ok(())349/// }350/// ```351#[stable(feature = "fs_read_write_bytes", since = "1.26.0")]352#[cfg_attr(not(test), rustc_diagnostic_item = "fs_read")]353pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {354 fn inner(path: &Path) -> io::Result<Vec<u8>> {355 let mut file = File::open(path)?;356 let size = file.metadata().map(|m| usize::try_from(m.len()).unwrap_or(usize::MAX)).ok();357 let mut bytes = Vec::try_with_capacity(size.unwrap_or(0))?;358 io::default_read_to_end(&mut file, &mut bytes, size)?;359 Ok(bytes)360 }361 inner(path.as_ref())362}363364/// Reads the entire contents of a file into a string.365///366/// This is a convenience function for using [`File::open`] and [`read_to_string`]367/// with fewer imports and without an intermediate variable.368///369/// [`read_to_string`]: Read::read_to_string370///371/// # Errors372///373/// This function will return an error if `path` does not already exist.374/// Other errors may also be returned according to [`OpenOptions::open`].375///376/// If the contents of the file are not valid UTF-8, then an error will also be377/// returned.378///379/// While reading from the file, this function handles [`io::ErrorKind::Interrupted`]380/// with automatic retries. See [io::Read] documentation for details.381///382/// # Examples383///384/// ```no_run385/// use std::fs;386/// use std::error::Error;387///388/// fn main() -> Result<(), Box<dyn Error>> {389/// let message: String = fs::read_to_string("message.txt")?;390/// println!("{}", message);391/// Ok(())392/// }393/// ```394#[stable(feature = "fs_read_write", since = "1.26.0")]395#[cfg_attr(not(test), rustc_diagnostic_item = "fs_read_to_string")]396pub fn read_to_string<P: AsRef<Path>>(path: P) -> io::Result<String> {397 fn inner(path: &Path) -> io::Result<String> {398 let mut file = File::open(path)?;399 let size = file.metadata().map(|m| usize::try_from(m.len()).unwrap_or(usize::MAX)).ok();400 let mut string = String::new();401 string.try_reserve_exact(size.unwrap_or(0))?;402 io::default_read_to_string(&mut file, &mut string, size)?;403 Ok(string)404 }405 inner(path.as_ref())406}407408/// Writes a slice as the entire contents of a file.409///410/// This function will create a file if it does not exist,411/// and will entirely replace its contents if it does.412///413/// Depending on the platform, this function may fail if the414/// full directory path does not exist.415///416/// This is a convenience function for using [`File::create`] and [`write_all`]417/// with fewer imports.418///419/// [`write_all`]: Write::write_all420///421/// # Examples422///423/// ```no_run424/// use std::fs;425///426/// fn main() -> std::io::Result<()> {427/// fs::write("foo.txt", b"Lorem ipsum")?;428/// fs::write("bar.txt", "dolor sit")?;429/// Ok(())430/// }431/// ```432#[stable(feature = "fs_read_write_bytes", since = "1.26.0")]433#[cfg_attr(not(test), rustc_diagnostic_item = "fs_write")]434pub fn write<P: AsRef<Path>, C: AsRef<[u8]>>(path: P, contents: C) -> io::Result<()> {435 fn inner(path: &Path, contents: &[u8]) -> io::Result<()> {436 File::create(path)?.write_all(contents)437 }438 inner(path.as_ref(), contents.as_ref())439}440441/// Changes the timestamps of the file or directory at the specified path.442///443/// This function will attempt to set the access and modification times444/// to the times specified. If the path refers to a symbolic link, this function445/// will follow the link and change the timestamps of the target file.446///447/// # Platform-specific behavior448///449/// This function currently corresponds to the `utimensat` function on Unix platforms, the450/// `setattrlist` function on Apple platforms, and the `SetFileTime` function on Windows.451///452/// # Errors453///454/// This function will return an error if the user lacks permission to change timestamps on the455/// target file or symlink. It may also return an error if the OS does not support it.456///457/// # Examples458///459/// ```no_run460/// use std::fs::{self, FileTimes};461/// use std::time::SystemTime;462///463/// fn main() -> std::io::Result<()> {464/// let now = SystemTime::now();465/// let times = FileTimes::new()466/// .set_accessed(now)467/// .set_modified(now);468/// fs::set_times("foo.txt", times)?;469/// Ok(())470/// }471/// ```472#[stable(feature = "fs_set_times", since = "1.99.0")]473#[doc(alias = "utimens")]474#[doc(alias = "utimes")]475#[doc(alias = "utime")]476#[cfg_attr(not(test), rustc_diagnostic_item = "fs_set_times")]477pub fn set_times<P: AsRef<Path>>(path: P, times: FileTimes) -> io::Result<()> {478 fs_imp::set_times(path.as_ref(), times.0)479}480481/// Changes the timestamps of the file or symlink at the specified path.482///483/// This function will attempt to set the access and modification times484/// to the times specified. Differ from `set_times`, if the path refers to a symbolic link,485/// this function will change the timestamps of the symlink itself, not the target file.486///487/// # Platform-specific behavior488///489/// This function currently corresponds to the `utimensat` function with `AT_SYMLINK_NOFOLLOW` on490/// Unix platforms, the `setattrlist` function with `FSOPT_NOFOLLOW` on Apple platforms, and the491/// `SetFileTime` function on Windows.492///493/// # Errors494///495/// This function will return an error if the user lacks permission to change timestamps on the496/// target file or symlink. It may also return an error if the OS does not support it.497///498/// # Examples499///500/// ```no_run501/// use std::fs::{self, FileTimes};502/// use std::time::SystemTime;503///504/// fn main() -> std::io::Result<()> {505/// let now = SystemTime::now();506/// let times = FileTimes::new()507/// .set_accessed(now)508/// .set_modified(now);509/// fs::set_times_nofollow("symlink.txt", times)?;510/// Ok(())511/// }512/// ```513#[stable(feature = "fs_set_times", since = "1.99.0")]514#[doc(alias = "utimensat")]515#[doc(alias = "lutimens")]516#[doc(alias = "lutimes")]517#[cfg_attr(not(test), rustc_diagnostic_item = "fs_set_times_nofollow")]518pub fn set_times_nofollow<P: AsRef<Path>>(path: P, times: FileTimes) -> io::Result<()> {519 fs_imp::set_times_nofollow(path.as_ref(), times.0)520}521522#[stable(feature = "file_lock", since = "1.89.0")]523impl error::Error for TryLockError {}524525#[stable(feature = "file_lock", since = "1.89.0")]526impl fmt::Debug for TryLockError {527 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {528 match self {529 TryLockError::Error(err) => err.fmt(f),530 TryLockError::WouldBlock => "WouldBlock".fmt(f),531 }532 }533}534535#[stable(feature = "file_lock", since = "1.89.0")]536impl fmt::Display for TryLockError {537 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {538 match self {539 TryLockError::Error(_) => "lock acquisition failed due to I/O error",540 TryLockError::WouldBlock => "lock acquisition failed because the operation would block",541 }542 .fmt(f)543 }544}545546#[stable(feature = "file_lock", since = "1.89.0")]547impl From<TryLockError> for io::Error {548 fn from(err: TryLockError) -> io::Error {549 match err {550 TryLockError::Error(err) => err,551 TryLockError::WouldBlock => io::ErrorKind::WouldBlock.into(),552 }553 }554}555556impl File {557 /// Attempts to open a file in read-only mode.558 ///559 /// See the [`OpenOptions::open`] method for more details.560 ///561 /// If you only need to read the entire file contents,562 /// consider [`std::fs::read()`][self::read] or563 /// [`std::fs::read_to_string()`][self::read_to_string] instead.564 ///565 /// # Errors566 ///567 /// This function will return an error if `path` does not already exist.568 /// Other errors may also be returned according to [`OpenOptions::open`].569 ///570 /// # Examples571 ///572 /// ```no_run573 /// use std::fs::File;574 /// use std::io::Read;575 ///576 /// fn main() -> std::io::Result<()> {577 /// let mut f = File::open("foo.txt")?;578 /// let mut data = vec![];579 /// f.read_to_end(&mut data)?;580 /// Ok(())581 /// }582 /// ```583 #[stable(feature = "rust1", since = "1.0.0")]584 pub fn open<P: AsRef<Path>>(path: P) -> io::Result<File> {585 OpenOptions::new().read(true).open(path.as_ref())586 }587588 /// Attempts to open a file in read-only mode with buffering.589 ///590 /// See the [`OpenOptions::open`] method, the [`BufReader`][io::BufReader] type,591 /// and the [`BufRead`][io::BufRead] trait for more details.592 ///593 /// If you only need to read the entire file contents,594 /// consider [`std::fs::read()`][self::read] or595 /// [`std::fs::read_to_string()`][self::read_to_string] instead.596 ///597 /// # Errors598 ///599 /// This function will return an error if `path` does not already exist,600 /// or if memory allocation fails for the new buffer.601 /// Other errors may also be returned according to [`OpenOptions::open`].602 ///603 /// # Examples604 ///605 /// ```no_run606 /// #![feature(file_buffered)]607 /// use std::fs::File;608 /// use std::io::BufRead;609 ///610 /// fn main() -> std::io::Result<()> {611 /// let mut f = File::open_buffered("foo.txt")?;612 /// assert!(f.capacity() > 0);613 /// for (line, i) in f.lines().zip(1..) {614 /// println!("{i:6}: {}", line?);615 /// }616 /// Ok(())617 /// }618 /// ```619 #[unstable(feature = "file_buffered", issue = "130804")]620 pub fn open_buffered<P: AsRef<Path>>(path: P) -> io::Result<io::BufReader<File>> {621 // Allocate the buffer *first* so we don't affect the filesystem otherwise.622 io::BufReader::try_new_with(|| File::open(path))623 }624625 /// Opens a file in write-only mode.626 ///627 /// This function will create a file if it does not exist,628 /// and will truncate it if it does.629 ///630 /// Depending on the platform, this function may fail if the631 /// full directory path does not exist.632 /// See the [`OpenOptions::open`] function for more details.633 ///634 /// See also [`std::fs::write()`][self::write] for a simple function to635 /// create a file with some given data.636 ///637 /// # Examples638 ///639 /// ```no_run640 /// use std::fs::File;641 /// use std::io::Write;642 ///643 /// fn main() -> std::io::Result<()> {644 /// let mut f = File::create("foo.txt")?;645 /// f.write_all(&1234_u32.to_be_bytes())?;646 /// Ok(())647 /// }648 /// ```649 #[stable(feature = "rust1", since = "1.0.0")]650 pub fn create<P: AsRef<Path>>(path: P) -> io::Result<File> {651 OpenOptions::new().write(true).create(true).truncate(true).open(path.as_ref())652 }653654 /// Opens a file in write-only mode with buffering.655 ///656 /// This function will create a file if it does not exist,657 /// and will truncate it if it does.658 ///659 /// Depending on the platform, this function may fail if the660 /// full directory path does not exist.661 ///662 /// See the [`OpenOptions::open`] method and the663 /// [`BufWriter`][io::BufWriter] type for more details.664 ///665 /// See also [`std::fs::write()`][self::write] for a simple function to666 /// create a file with some given data.667 ///668 /// # Examples669 ///670 /// ```no_run671 /// #![feature(file_buffered)]672 /// use std::fs::File;673 /// use std::io::Write;674 ///675 /// fn main() -> std::io::Result<()> {676 /// let mut f = File::create_buffered("foo.txt")?;677 /// assert!(f.capacity() > 0);678 /// for i in 0..100 {679 /// writeln!(&mut f, "{i}")?;680 /// }681 /// f.flush()?;682 /// Ok(())683 /// }684 /// ```685 #[unstable(feature = "file_buffered", issue = "130804")]686 pub fn create_buffered<P: AsRef<Path>>(path: P) -> io::Result<io::BufWriter<File>> {687 // Allocate the buffer *first* so we don't affect the filesystem otherwise.688 io::BufWriter::try_new_with(|| File::create(path))689 }690691 /// Creates a new file in read-write mode; error if the file exists.692 ///693 /// This function will create a file if it does not exist, or return an error if it does. This694 /// way, if the call succeeds, the file returned is guaranteed to be new.695 /// If a file exists at the target location, creating a new file will fail with [`AlreadyExists`]696 /// or another error based on the situation. See [`OpenOptions::open`] for a697 /// non-exhaustive list of likely errors.698 ///699 /// This option is useful because it is atomic. Otherwise between checking whether a file700 /// exists and creating a new one, the file may have been created by another process (a [TOCTOU]701 /// race condition / attack).702 ///703 /// This can also be written using704 /// `File::options().read(true).write(true).create_new(true).open(...)`.705 ///706 /// [`AlreadyExists`]: crate::io::ErrorKind::AlreadyExists707 /// [TOCTOU]: self#time-of-check-to-time-of-use-toctou708 ///709 /// # Examples710 ///711 /// ```no_run712 /// use std::fs::File;713 /// use std::io::Write;714 ///715 /// fn main() -> std::io::Result<()> {716 /// let mut f = File::create_new("foo.txt")?;717 /// f.write_all("Hello, world!".as_bytes())?;718 /// Ok(())719 /// }720 /// ```721 #[stable(feature = "file_create_new", since = "1.77.0")]722 pub fn create_new<P: AsRef<Path>>(path: P) -> io::Result<File> {723 OpenOptions::new().read(true).write(true).create_new(true).open(path.as_ref())724 }725726 /// Returns a new OpenOptions object.727 ///728 /// This function returns a new OpenOptions object that you can use to729 /// open or create a file with specific options if `open()` or `create()`730 /// are not appropriate.731 ///732 /// It is equivalent to `OpenOptions::new()`, but allows you to write more733 /// readable code. Instead of734 /// `OpenOptions::new().append(true).open("example.log")`,735 /// you can write `File::options().append(true).open("example.log")`. This736 /// also avoids the need to import `OpenOptions`.737 ///738 /// See the [`OpenOptions::new`] function for more details.739 ///740 /// # Examples741 ///742 /// ```no_run743 /// use std::fs::File;744 /// use std::io::Write;745 ///746 /// fn main() -> std::io::Result<()> {747 /// let mut f = File::options().append(true).open("example.log")?;748 /// writeln!(&mut f, "new line")?;749 /// Ok(())750 /// }751 /// ```752 #[must_use]753 #[stable(feature = "with_options", since = "1.58.0")]754 #[cfg_attr(not(test), rustc_diagnostic_item = "file_options")]755 pub fn options() -> OpenOptions {756 OpenOptions::new()757 }758759 /// Attempts to sync all OS-internal file content and metadata to disk.760 ///761 /// This function will attempt to ensure that all in-memory data reaches the762 /// filesystem before returning.763 ///764 /// This can be used to handle errors that would otherwise only be caught765 /// when the `File` is closed, as dropping a `File` will ignore all errors.766 /// Note, however, that `sync_all` is generally more expensive than closing767 /// a file by dropping it, because the latter is not required to block until768 /// the data has been written to the filesystem.769 ///770 /// If synchronizing the metadata is not required, use [`sync_data`] instead.771 ///772 /// [`sync_data`]: File::sync_data773 ///774 /// # Examples775 ///776 /// ```no_run777 /// use std::fs::File;778 /// use std::io::prelude::*;779 ///780 /// fn main() -> std::io::Result<()> {781 /// let mut f = File::create("foo.txt")?;782 /// f.write_all(b"Hello, world!")?;783 ///784 /// f.sync_all()?;785 /// Ok(())786 /// }787 /// ```788 #[stable(feature = "rust1", since = "1.0.0")]789 #[doc(alias = "fsync")]790 pub fn sync_all(&self) -> io::Result<()> {791 self.inner.fsync()792 }793794 /// This function is similar to [`sync_all`], except that it might not795 /// synchronize file metadata to the filesystem.796 ///797 /// This is intended for use cases that must synchronize content, but don't798 /// need the metadata on disk. The goal of this method is to reduce disk799 /// operations.800 ///801 /// Note that some platforms may simply implement this in terms of802 /// [`sync_all`].803 ///804 /// [`sync_all`]: File::sync_all805 ///806 /// # Examples807 ///808 /// ```no_run809 /// use std::fs::File;810 /// use std::io::prelude::*;811 ///812 /// fn main() -> std::io::Result<()> {813 /// let mut f = File::create("foo.txt")?;814 /// f.write_all(b"Hello, world!")?;815 ///816 /// f.sync_data()?;817 /// Ok(())818 /// }819 /// ```820 #[stable(feature = "rust1", since = "1.0.0")]821 #[doc(alias = "fdatasync")]822 pub fn sync_data(&self) -> io::Result<()> {823 self.inner.datasync()824 }825826 /// Acquire an exclusive lock on the file. Blocks until the lock can be acquired.827 ///828 /// This acquires an exclusive lock. No *other* file handle to this file, in this or any other829 /// process, may acquire another lock.830 /// If this file handle/descriptor, or a clone of it, already holds a lock, the exact behavior831 /// is unspecified and platform dependent, including the possibility that it will deadlock.832 /// However, if this method returns, then an exclusive lock is held.833 ///834 /// This lock may be advisory or mandatory. This lock is meant to interact with [`lock`],835 /// [`try_lock`], [`lock_shared`], [`try_lock_shared`], and [`unlock`]. Its interactions with836 /// other methods, such as [`read`] and [`write`] are platform specific, and it may or may not837 /// cause non-lockholders to block.838 ///839 /// If the file is not open for writing, it is unspecified whether this function returns an error.840 ///841 /// The lock will be released when this file (along with any other file descriptors/handles842 /// duplicated or inherited from it) is closed, or if the [`unlock`] method is called.843 ///844 /// # Platform-specific behavior845 ///846 /// This function currently corresponds to the `flock` function on Unix with the `LOCK_EX` flag,847 /// and the `LockFileEx` function on Windows with the `LOCKFILE_EXCLUSIVE_LOCK` flag. Note that,848 /// this [may change in the future][changes].849 ///850 /// On Windows, locking a file will fail if the file is opened only for append. To lock a file,851 /// open it with one of `.read(true)`, `.read(true).append(true)`, or `.write(true)`.852 ///853 /// [changes]: io#platform-specific-behavior854 ///855 /// [`lock`]: File::lock856 /// [`lock_shared`]: File::lock_shared857 /// [`try_lock`]: File::try_lock858 /// [`try_lock_shared`]: File::try_lock_shared859 /// [`unlock`]: File::unlock860 /// [`read`]: Read::read861 /// [`write`]: Write::write862 ///863 /// # Examples864 ///865 /// ```no_run866 /// use std::fs::File;867 ///868 /// fn main() -> std::io::Result<()> {869 /// let f = File::create("foo.txt")?;870 /// f.lock()?;871 /// Ok(())872 /// }873 /// ```874 #[stable(feature = "file_lock", since = "1.89.0")]875 pub fn lock(&self) -> io::Result<()> {876 self.inner.lock()877 }878879 /// Acquire a shared (non-exclusive) lock on the file. Blocks until the lock can be acquired.880 ///881 /// This acquires a shared lock. More than one file handle to this file, in this or any other882 /// process, may hold a shared lock, but no *other* file handle may hold an exclusive lock at883 /// the same time.884 /// If this file handle/descriptor, or a clone of it, already holds a lock, the exact885 /// behavior is unspecified and platform dependent, including the possibility that it will886 /// deadlock. However, if this method returns, then a shared lock is held.887 ///888 /// This lock may be advisory or mandatory. This lock is meant to interact with [`lock`],889 /// [`try_lock`], [`lock_shared`], [`try_lock_shared`], and [`unlock`]. Its interactions with890 /// other methods, such as [`read`] and [`write`] are platform specific, and it may or may not891 /// cause non-lockholders to block.892 ///893 /// The lock will be released when this file (along with any other file descriptors/handles894 /// duplicated or inherited from it) is closed, or if the [`unlock`] method is called.895 ///896 /// # Platform-specific behavior897 ///898 /// This function currently corresponds to the `flock` function on Unix with the `LOCK_SH` flag,899 /// and the `LockFileEx` function on Windows. Note that, this900 /// [may change in the future][changes].901 ///902 /// On Windows, locking a file will fail if the file is opened only for append. To lock a file,903 /// open it with one of `.read(true)`, `.read(true).append(true)`, or `.write(true)`.904 ///905 /// [changes]: io#platform-specific-behavior906 ///907 /// [`lock`]: File::lock908 /// [`lock_shared`]: File::lock_shared909 /// [`try_lock`]: File::try_lock910 /// [`try_lock_shared`]: File::try_lock_shared911 /// [`unlock`]: File::unlock912 /// [`read`]: Read::read913 /// [`write`]: Write::write914 ///915 /// # Examples916 ///917 /// ```no_run918 /// use std::fs::File;919 ///920 /// fn main() -> std::io::Result<()> {921 /// let f = File::open("foo.txt")?;922 /// f.lock_shared()?;923 /// Ok(())924 /// }925 /// ```926 #[stable(feature = "file_lock", since = "1.89.0")]927 pub fn lock_shared(&self) -> io::Result<()> {928 self.inner.lock_shared()929 }930931 /// Try to acquire an exclusive lock on the file.932 ///933 /// Returns `Err(TryLockError::WouldBlock)` if a different lock is already held on this file934 /// (via another handle/descriptor).935 ///936 /// This acquires an exclusive lock; no other file handle to this file, in this or any other937 /// process, may acquire another lock.938 ///939 /// This lock may be advisory or mandatory. This lock is meant to interact with [`lock`],940 /// [`try_lock`], [`lock_shared`], [`try_lock_shared`], and [`unlock`]. Its interactions with941 /// other methods, such as [`read`] and [`write`] are platform specific, and it may or may not942 /// cause non-lockholders to block.943 ///944 /// If this file handle/descriptor, or a clone of it, already holds a lock, the exact behavior945 /// is unspecified and platform dependent, including the possibility that it will deadlock.946 /// However, if this method returns `Ok(())`, then it has acquired an exclusive lock.947 ///948 /// If the file is not open for writing, it is unspecified whether this function returns an error.949 ///950 /// The lock will be released when this file (along with any other file descriptors/handles951 /// duplicated or inherited from it) is closed, or if the [`unlock`] method is called.952 ///953 /// # Platform-specific behavior954 ///955 /// This function currently corresponds to the `flock` function on Unix with the `LOCK_EX` and956 /// `LOCK_NB` flags, and the `LockFileEx` function on Windows with the `LOCKFILE_EXCLUSIVE_LOCK`957 /// and `LOCKFILE_FAIL_IMMEDIATELY` flags. Note that, this958 /// [may change in the future][changes].959 ///960 /// On Windows, locking a file will fail if the file is opened only for append. To lock a file,961 /// open it with one of `.read(true)`, `.read(true).append(true)`, or `.write(true)`.962 ///963 /// [changes]: io#platform-specific-behavior964 ///965 /// [`lock`]: File::lock966 /// [`lock_shared`]: File::lock_shared967 /// [`try_lock`]: File::try_lock968 /// [`try_lock_shared`]: File::try_lock_shared969 /// [`unlock`]: File::unlock970 /// [`read`]: Read::read971 /// [`write`]: Write::write972 ///973 /// # Examples974 ///975 /// ```no_run976 /// use std::fs::{File, TryLockError};977 ///978 /// fn main() -> std::io::Result<()> {979 /// let f = File::create("foo.txt")?;980 /// // Explicit handling of the WouldBlock error981 /// match f.try_lock() {982 /// Ok(_) => (),983 /// Err(TryLockError::WouldBlock) => (), // Lock not acquired984 /// Err(TryLockError::Error(err)) => return Err(err),985 /// }986 /// // Alternately, propagate the error as an io::Error987 /// f.try_lock()?;988 /// Ok(())989 /// }990 /// ```991 #[stable(feature = "file_lock", since = "1.89.0")]992 pub fn try_lock(&self) -> Result<(), TryLockError> {993 self.inner.try_lock()994 }995996 /// Try to acquire a shared (non-exclusive) lock on the file.997 ///998 /// Returns `Err(TryLockError::WouldBlock)` if a different lock is already held on this file999 /// (via another handle/descriptor).1000 ///1001 /// This acquires a shared lock; more than one file handle, in this or any other process, may1002 /// hold a shared lock, but none may hold an exclusive lock at the same time.1003 ///1004 /// This lock may be advisory or mandatory. This lock is meant to interact with [`lock`],1005 /// [`try_lock`], [`lock_shared`], [`try_lock_shared`], and [`unlock`]. Its interactions with1006 /// other methods, such as [`read`] and [`write`] are platform specific, and it may or may not1007 /// cause non-lockholders to block.1008 ///1009 /// If this file handle, or a clone of it, already holds a lock, the exact behavior is1010 /// unspecified and platform dependent, including the possibility that it will deadlock.1011 /// However, if this method returns `Ok(())`, then it has acquired a shared lock.1012 ///1013 /// The lock will be released when this file (along with any other file descriptors/handles1014 /// duplicated or inherited from it) is closed, or if the [`unlock`] method is called.1015 ///1016 /// # Platform-specific behavior1017 ///1018 /// This function currently corresponds to the `flock` function on Unix with the `LOCK_SH` and1019 /// `LOCK_NB` flags, and the `LockFileEx` function on Windows with the1020 /// `LOCKFILE_FAIL_IMMEDIATELY` flag. Note that, this1021 /// [may change in the future][changes].1022 ///1023 /// On Windows, locking a file will fail if the file is opened only for append. To lock a file,1024 /// open it with one of `.read(true)`, `.read(true).append(true)`, or `.write(true)`.1025 ///1026 /// [changes]: io#platform-specific-behavior1027 ///1028 /// [`lock`]: File::lock1029 /// [`lock_shared`]: File::lock_shared1030 /// [`try_lock`]: File::try_lock1031 /// [`try_lock_shared`]: File::try_lock_shared1032 /// [`unlock`]: File::unlock1033 /// [`read`]: Read::read1034 /// [`write`]: Write::write1035 ///1036 /// # Examples1037 ///1038 /// ```no_run1039 /// use std::fs::{File, TryLockError};1040 ///1041 /// fn main() -> std::io::Result<()> {1042 /// let f = File::open("foo.txt")?;1043 /// // Explicit handling of the WouldBlock error1044 /// match f.try_lock_shared() {1045 /// Ok(_) => (),1046 /// Err(TryLockError::WouldBlock) => (), // Lock not acquired1047 /// Err(TryLockError::Error(err)) => return Err(err),1048 /// }1049 /// // Alternately, propagate the error as an io::Error1050 /// f.try_lock_shared()?;1051 ///1052 /// Ok(())1053 /// }1054 /// ```1055 #[stable(feature = "file_lock", since = "1.89.0")]1056 pub fn try_lock_shared(&self) -> Result<(), TryLockError> {1057 self.inner.try_lock_shared()1058 }10591060 /// Release all locks on the file.1061 ///1062 /// All locks are released when the file (along with any other file descriptors/handles1063 /// duplicated or inherited from it) is closed. This method allows releasing locks without1064 /// closing the file.1065 ///1066 /// If no lock is currently held via this file descriptor/handle, this method may return an1067 /// error, or may return successfully without taking any action.1068 ///1069 /// # Platform-specific behavior1070 ///1071 /// This function currently corresponds to the `flock` function on Unix with the `LOCK_UN` flag,1072 /// and the `UnlockFile` function on Windows. Note that, this1073 /// [may change in the future][changes].1074 ///1075 /// On Windows, locking a file will fail if the file is opened only for append. To lock a file,1076 /// open it with one of `.read(true)`, `.read(true).append(true)`, or `.write(true)`.1077 ///1078 /// [changes]: io#platform-specific-behavior1079 ///1080 /// # Examples1081 ///1082 /// ```no_run1083 /// use std::fs::File;1084 ///1085 /// fn main() -> std::io::Result<()> {1086 /// let f = File::open("foo.txt")?;1087 /// f.lock()?;1088 /// f.unlock()?;1089 /// Ok(())1090 /// }1091 /// ```1092 #[stable(feature = "file_lock", since = "1.89.0")]1093 pub fn unlock(&self) -> io::Result<()> {1094 self.inner.unlock()1095 }10961097 /// Truncates or extends the underlying file, updating the size of1098 /// this file to become `size`.1099 ///1100 /// If the `size` is less than the current file's size, then the file will1101 /// be shrunk. If it is greater than the current file's size, then the file1102 /// will be extended to `size` and have all of the intermediate data filled1103 /// in with 0s.1104 ///1105 /// The file's cursor isn't changed. In particular, if the cursor was at the1106 /// end and the file is shrunk using this operation, the cursor will now be1107 /// past the end.1108 ///1109 /// # Errors1110 ///1111 /// This function will return an error if the file is not opened for writing.1112 /// Also, [`std::io::ErrorKind::InvalidInput`](crate::io::ErrorKind::InvalidInput)1113 /// will be returned if the desired length would cause an overflow due to1114 /// the implementation specifics.1115 ///1116 /// # Examples1117 ///1118 /// ```no_run1119 /// use std::fs::File;1120 ///1121 /// fn main() -> std::io::Result<()> {1122 /// let mut f = File::create("foo.txt")?;1123 /// f.set_len(10)?;1124 /// Ok(())1125 /// }1126 /// ```1127 ///1128 /// Note that this method alters the content of the underlying file, even1129 /// though it takes `&self` rather than `&mut self`.1130 #[stable(feature = "rust1", since = "1.0.0")]1131 pub fn set_len(&self, size: u64) -> io::Result<()> {1132 self.inner.truncate(size)1133 }11341135 /// Queries metadata about the underlying file.1136 ///1137 /// # Examples1138 ///1139 /// ```no_run1140 /// use std::fs::File;1141 ///1142 /// fn main() -> std::io::Result<()> {1143 /// let mut f = File::open("foo.txt")?;1144 /// let metadata = f.metadata()?;1145 /// Ok(())1146 /// }1147 /// ```1148 #[stable(feature = "rust1", since = "1.0.0")]1149 pub fn metadata(&self) -> io::Result<Metadata> {1150 self.inner.file_attr().map(Metadata)1151 }11521153 /// Creates a new `File` instance that shares the same underlying file handle1154 /// as the existing `File` instance. Reads, writes, and seeks will affect1155 /// both `File` instances simultaneously.1156 ///1157 /// # Examples1158 ///1159 /// Creates two handles for a file named `foo.txt`:1160 ///1161 /// ```no_run1162 /// use std::fs::File;1163 ///1164 /// fn main() -> std::io::Result<()> {1165 /// let mut file = File::open("foo.txt")?;1166 /// let file_copy = file.try_clone()?;1167 /// Ok(())1168 /// }1169 /// ```1170 ///1171 /// Assuming there’s a file named `foo.txt` with contents `abcdef\n`, create1172 /// two handles, seek one of them, and read the remaining bytes from the1173 /// other handle:1174 ///1175 /// ```no_run1176 /// use std::fs::File;1177 /// use std::io::SeekFrom;1178 /// use std::io::prelude::*;1179 ///1180 /// fn main() -> std::io::Result<()> {1181 /// let mut file = File::open("foo.txt")?;1182 /// let mut file_copy = file.try_clone()?;1183 ///1184 /// file.seek(SeekFrom::Start(3))?;1185 ///1186 /// let mut contents = vec![];1187 /// file_copy.read_to_end(&mut contents)?;1188 /// assert_eq!(contents, b"def\n");1189 /// Ok(())1190 /// }1191 /// ```1192 #[stable(feature = "file_try_clone", since = "1.9.0")]1193 pub fn try_clone(&self) -> io::Result<File> {1194 Ok(File { inner: self.inner.duplicate()? })1195 }11961197 /// Changes the permissions on the underlying file.1198 ///1199 /// # Platform-specific behavior1200 ///1201 /// This function currently corresponds to the `fchmod` function on Unix and1202 /// the `SetFileInformationByHandle` function on Windows. Note that, this1203 /// [may change in the future][changes].1204 ///1205 /// [changes]: io#platform-specific-behavior1206 ///1207 /// # Errors1208 ///1209 /// This function will return an error if the user lacks permission change1210 /// attributes on the underlying file. It may also return an error in other1211 /// os-specific unspecified cases.1212 ///1213 /// # Examples1214 ///1215 /// ```no_run1216 /// fn main() -> std::io::Result<()> {1217 /// use std::fs::File;1218 ///1219 /// let file = File::open("foo.txt")?;1220 /// let mut perms = file.metadata()?.permissions();1221 /// perms.set_readonly(true);1222 /// file.set_permissions(perms)?;1223 /// Ok(())1224 /// }1225 /// ```1226 ///1227 /// Note that this method alters the permissions of the underlying file,1228 /// even though it takes `&self` rather than `&mut self`.1229 #[doc(alias = "fchmod", alias = "SetFileInformationByHandle")]1230 #[stable(feature = "set_permissions_atomic", since = "1.16.0")]1231 pub fn set_permissions(&self, perm: Permissions) -> io::Result<()> {1232 self.inner.set_permissions(perm.0)1233 }12341235 /// Changes the timestamps of the underlying file.1236 ///1237 /// # Platform-specific behavior1238 ///1239 /// This function currently corresponds to the `futimens` function on Unix (falling back to1240 /// `futimes` on macOS before 10.13) and the `SetFileTime` function on Windows. Note that this1241 /// [may change in the future][changes].1242 ///1243 /// On most platforms, including UNIX and Windows platforms, this function can also change the1244 /// timestamps of a directory. To get a `File` representing a directory in order to call1245 /// `set_times`, open the directory with `File::open` without attempting to obtain write1246 /// permission.1247 ///1248 /// [changes]: io#platform-specific-behavior1249 ///1250 /// # Errors1251 ///1252 /// This function will return an error if the user lacks permission to change timestamps on the1253 /// underlying file. It may also return an error in other os-specific unspecified cases.1254 ///1255 /// This function may return an error if the operating system lacks support to change one or1256 /// more of the timestamps set in the `FileTimes` structure.1257 ///1258 /// # Examples1259 ///1260 /// ```no_run1261 /// fn main() -> std::io::Result<()> {1262 /// use std::fs::{self, File, FileTimes};1263 ///1264 /// let src = fs::metadata("src")?;1265 /// let dest = File::open("dest")?;1266 /// let times = FileTimes::new()1267 /// .set_accessed(src.accessed()?)1268 /// .set_modified(src.modified()?);1269 /// dest.set_times(times)?;1270 /// Ok(())1271 /// }1272 /// ```1273 #[stable(feature = "file_set_times", since = "1.75.0")]1274 #[doc(alias = "futimens")]1275 #[doc(alias = "futimes")]1276 #[doc(alias = "SetFileTime")]1277 #[doc(alias = "filetime")]1278 pub fn set_times(&self, times: FileTimes) -> io::Result<()> {1279 self.inner.set_times(times.0)1280 }12811282 /// Changes the modification time of the underlying file.1283 ///1284 /// This is an alias for `set_times(FileTimes::new().set_modified(time))`.1285 #[stable(feature = "file_set_times", since = "1.75.0")]1286 #[inline]1287 pub fn set_modified(&self, time: SystemTime) -> io::Result<()> {1288 self.set_times(FileTimes::new().set_modified(time))1289 }1290}12911292// In addition to the `impl`s here, `File` also has `impl`s for1293// `AsFd`/`From<OwnedFd>`/`Into<OwnedFd>` and1294// `AsRawFd`/`IntoRawFd`/`FromRawFd`, on Unix and WASI, and1295// `AsHandle`/`From<OwnedHandle>`/`Into<OwnedHandle>` and1296// `AsRawHandle`/`IntoRawHandle`/`FromRawHandle` on Windows.12971298impl AsInner<fs_imp::File> for File {1299 #[inline]1300 fn as_inner(&self) -> &fs_imp::File {1301 &self.inner1302 }1303}1304impl FromInner<fs_imp::File> for File {1305 fn from_inner(f: fs_imp::File) -> File {1306 File { inner: f }1307 }1308}1309impl IntoInner<fs_imp::File> for File {1310 fn into_inner(self) -> fs_imp::File {1311 self.inner1312 }1313}13141315#[stable(feature = "rust1", since = "1.0.0")]1316impl fmt::Debug for File {1317 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {1318 self.inner.fmt(f)1319 }1320}13211322/// Indicates how much extra capacity is needed to read the rest of the file.1323fn buffer_capacity_required(mut file: &File) -> Option<usize> {1324 let size = file.metadata().map(|m| m.len()).ok()?;1325 let pos = file.stream_position().ok()?;1326 // Don't worry about `usize` overflow because reading will fail regardless1327 // in that case.1328 Some(size.saturating_sub(pos) as usize)1329}13301331#[stable(feature = "rust1", since = "1.0.0")]1332impl Read for &File {1333 /// Reads some bytes from the file.1334 ///1335 /// See [`Read::read`] docs for more info.1336 ///1337 /// # Platform-specific behavior1338 ///1339 /// This function currently corresponds to the `read` function on Unix and1340 /// the `NtReadFile` function on Windows. Note that this [may change in1341 /// the future][changes].1342 ///1343 /// [changes]: io#platform-specific-behavior1344 #[inline]1345 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {1346 self.inner.read(buf)1347 }13481349 /// Like `read`, except that it reads into a slice of buffers.1350 ///1351 /// See [`Read::read_vectored`] docs for more info.1352 ///1353 /// # Platform-specific behavior1354 ///1355 /// This function currently corresponds to the `readv` function on Unix and1356 /// falls back to the `read` implementation on Windows. Note that this1357 /// [may change in the future][changes].1358 ///1359 /// [changes]: io#platform-specific-behavior1360 #[inline]1361 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {1362 self.inner.read_vectored(bufs)1363 }13641365 #[inline]1366 fn read_buf(&mut self, cursor: BorrowedCursor<'_, u8>) -> io::Result<()> {1367 self.inner.read_buf(cursor)1368 }13691370 /// Determines if `File` has an efficient `read_vectored` implementation.1371 ///1372 /// See [`Read::is_read_vectored`] docs for more info.1373 ///1374 /// # Platform-specific behavior1375 ///1376 /// This function currently returns `true` on Unix and `false` on Windows.1377 /// Note that this [may change in the future][changes].1378 ///1379 /// [changes]: io#platform-specific-behavior1380 #[inline]1381 fn is_read_vectored(&self) -> bool {1382 self.inner.is_read_vectored()1383 }13841385 // Reserves space in the buffer based on the file size when available.1386 fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {1387 let size = buffer_capacity_required(self);1388 buf.try_reserve(size.unwrap_or(0))?;1389 io::default_read_to_end(self, buf, size)1390 }13911392 // Reserves space in the buffer based on the file size when available.1393 fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {1394 let size = buffer_capacity_required(self);1395 buf.try_reserve(size.unwrap_or(0))?;1396 io::default_read_to_string(self, buf, size)1397 }1398}1399#[stable(feature = "rust1", since = "1.0.0")]1400impl Write for &File {1401 /// Writes some bytes to the file.1402 ///1403 /// See [`Write::write`] docs for more info.1404 ///1405 /// # Platform-specific behavior1406 ///1407 /// This function currently corresponds to the `write` function on Unix and1408 /// the `NtWriteFile` function on Windows. Note that this [may change in1409 /// the future][changes].1410 ///1411 /// [changes]: io#platform-specific-behavior1412 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {1413 self.inner.write(buf)1414 }14151416 /// Like `write`, except that it writes into a slice of buffers.1417 ///1418 /// See [`Write::write_vectored`] docs for more info.1419 ///1420 /// # Platform-specific behavior1421 ///1422 /// This function currently corresponds to the `writev` function on Unix1423 /// and falls back to the `write` implementation on Windows. Note that this1424 /// [may change in the future][changes].1425 ///1426 /// [changes]: io#platform-specific-behavior1427 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {1428 self.inner.write_vectored(bufs)1429 }14301431 /// Determines if `File` has an efficient `write_vectored` implementation.1432 ///1433 /// See [`Write::is_write_vectored`] docs for more info.1434 ///1435 /// # Platform-specific behavior1436 ///1437 /// This function currently returns `true` on Unix and `false` on Windows.1438 /// Note that this [may change in the future][changes].1439 ///1440 /// [changes]: io#platform-specific-behavior1441 #[inline]1442 fn is_write_vectored(&self) -> bool {1443 self.inner.is_write_vectored()1444 }14451446 /// Flushes the file, ensuring that all intermediately buffered contents1447 /// reach their destination.1448 ///1449 /// See [`Write::flush`] docs for more info.1450 ///1451 /// # Platform-specific behavior1452 ///1453 /// Since a `File` structure doesn't contain any buffers, this function is1454 /// currently a no-op on Unix and Windows. Note that this [may change in1455 /// the future][changes].1456 ///1457 /// [changes]: io#platform-specific-behavior1458 #[inline]1459 fn flush(&mut self) -> io::Result<()> {1460 self.inner.flush()1461 }1462}1463#[stable(feature = "rust1", since = "1.0.0")]1464impl Seek for &File {1465 /// Seek to an offset, in bytes in a file.1466 ///1467 /// See [`Seek::seek`] docs for more info.1468 ///1469 /// # Platform-specific behavior1470 ///1471 /// This function currently corresponds to the `lseek64` function on Unix1472 /// and the `SetFilePointerEx` function on Windows. Note that this [may1473 /// change in the future][changes].1474 ///1475 /// [changes]: io#platform-specific-behavior1476 fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {1477 self.inner.seek(pos)1478 }14791480 /// Returns the length of this file (in bytes).1481 ///1482 /// See [`Seek::stream_len`] docs for more info.1483 ///1484 /// # Platform-specific behavior1485 ///1486 /// This function currently corresponds to the `statx` function on Linux1487 /// (with fallbacks) and the `GetFileSizeEx` function on Windows. Note that1488 /// this [may change in the future][changes].1489 ///1490 /// [changes]: io#platform-specific-behavior1491 fn stream_len(&mut self) -> io::Result<u64> {1492 if let Some(result) = self.inner.size() {1493 return result;1494 }1495 io::stream_len_default(self)1496 }14971498 fn stream_position(&mut self) -> io::Result<u64> {1499 self.inner.tell()1500 }1501}15021503#[stable(feature = "rust1", since = "1.0.0")]1504impl Read for File {1505 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {1506 (&*self).read(buf)1507 }1508 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {1509 (&*self).read_vectored(bufs)1510 }1511 fn read_buf(&mut self, cursor: BorrowedCursor<'_, u8>) -> io::Result<()> {1512 (&*self).read_buf(cursor)1513 }1514 #[inline]1515 fn is_read_vectored(&self) -> bool {1516 (&self).is_read_vectored()1517 }1518 fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {1519 (&*self).read_to_end(buf)1520 }1521 fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {1522 (&*self).read_to_string(buf)1523 }1524}1525#[stable(feature = "rust1", since = "1.0.0")]1526impl Write for File {1527 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {1528 (&*self).write(buf)1529 }1530 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {1531 (&*self).write_vectored(bufs)1532 }1533 #[inline]1534 fn is_write_vectored(&self) -> bool {1535 (&self).is_write_vectored()1536 }1537 #[inline]1538 fn flush(&mut self) -> io::Result<()> {1539 (&*self).flush()1540 }1541}1542#[stable(feature = "rust1", since = "1.0.0")]1543impl Seek for File {1544 fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {1545 (&*self).seek(pos)1546 }1547 fn stream_len(&mut self) -> io::Result<u64> {1548 (&*self).stream_len()1549 }1550 fn stream_position(&mut self) -> io::Result<u64> {1551 (&*self).stream_position()1552 }1553}1554#[doc(hidden)]1555#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]1556impl crate::io::IoHandle for File {}15571558impl Dir {1559 /// Attempts to open a directory at `path` in read-only mode.1560 ///1561 /// This function opens a directory. To open a file instead, see [`File::open`].1562 ///1563 /// # Errors1564 ///1565 /// This function will return an error if `path` does not point to an existing directory.1566 /// Other errors may also be returned according to [`OpenOptions::open`].1567 ///1568 /// # Examples1569 ///1570 /// ```no_run1571 /// #![feature(dirfd)]1572 /// use std::{fs::Dir, io};1573 ///1574 /// fn main() -> std::io::Result<()> {1575 /// let dir = Dir::open("foo")?;1576 /// let mut f = dir.open_file("bar.txt")?;1577 /// let contents = io::read_to_string(f)?;1578 /// assert_eq!(contents, "Hello, world!");1579 /// Ok(())1580 /// }1581 /// ```1582 #[unstable(feature = "dirfd", issue = "120426")]1583 pub fn open<P: AsRef<Path>>(path: P) -> io::Result<Self> {1584 fs_imp::Dir::open(path.as_ref(), &OpenOptions::new().read(true).0)1585 .map(|inner| Self { inner })1586 }15871588 /// Attempts to open a directory at `path` according to `opts`.1589 ///1590 /// This function opens a directory. To open a file instead, see [`File::open`].1591 ///1592 /// # Errors1593 ///1594 /// This function will return an error if `path` does not point to an existing directory.1595 /// Other errors may also be returned according to [`OpenOptions::open`].1596 ///1597 /// # Examples1598 ///1599 /// ```no_run1600 /// #![feature(dirfd)]1601 /// use std::{fs::{Dir, OpenOptions}, io};1602 ///1603 /// fn main() -> std::io::Result<()> {1604 /// let dir = Dir::open_with("foo", &OpenOptions::new().read(true))?;1605 /// let mut f = dir.open_file("bar.txt")?;1606 /// let contents = io::read_to_string(f)?;1607 /// assert_eq!(contents, "Hello, world!");1608 /// Ok(())1609 /// }1610 /// ```1611 #[unstable(feature = "dirfd", issue = "120426")]1612 pub fn open_with<P: AsRef<Path>>(path: P, opts: &OpenOptions) -> io::Result<Self> {1613 fs_imp::Dir::open(path.as_ref(), &opts.0).map(|inner| Self { inner })1614 }16151616 /// Attempts to open a directory at `path` with the minimum permissions for traversal.1617 ///1618 /// The permissions requested by this function are guaranteed to be sufficient to open a child1619 /// file or folder, but not necessarily to list all children.1620 ///1621 /// # Errors1622 ///1623 /// This function may return an error according to [`OpenOptions::open`].1624 ///1625 /// # Examples1626 ///1627 /// ```no_run1628 /// #![feature(dirfd)]1629 /// use std::{fs::Dir, io};1630 ///1631 /// fn main() -> std::io::Result<()> {1632 /// let foo = Dir::open_for_traversal("foo")?;1633 /// let foobar = foo.open_dir("bar")?;1634 /// let mut foobarbaz = foobar.open_file("baz")?;1635 /// let contents = io::read_to_string(foobarbaz)?;1636 /// assert_eq!(contents, "Hello, world!");1637 /// Ok(())1638 /// }1639 /// ```1640 #[unstable(feature = "dirfd", issue = "120426")]1641 pub fn open_for_traversal<P: AsRef<Path>>(path: P) -> io::Result<Self> {1642 fs_imp::Dir::open_for_traversal(path.as_ref()).map(|inner| Self { inner })1643 }16441645 /// Queries metadata about the underlying directory.1646 ///1647 /// This is equivalent to `dir.metadata(".")` but can be more efficient.1648 ///1649 /// # Examples1650 ///1651 /// ```no_run1652 /// #![feature(dirfd)]1653 /// use std::fs::Dir;1654 ///1655 /// fn main() -> std::io::Result<()> {1656 /// let dir = Dir::open("foo")?;1657 /// let metadata = dir.self_metadata()?;1658 /// Ok(())1659 /// }1660 /// ```1661 #[unstable(feature = "dirfd", issue = "120426")]1662 pub fn self_metadata(&self) -> io::Result<Metadata> {1663 self.inner.self_metadata().map(Metadata)1664 }16651666 /// Attempts to open a file in read-only mode relative to this directory.1667 ///1668 /// This function interprets `path` relative to the directory provided by `self`. To open a file1669 /// relative to the current working directory, or at an absolute path, see [`File::open`].1670 ///1671 /// # Errors1672 ///1673 /// This function will return an error if `path` does not point to an existing file.1674 /// Other errors may also be returned according to [`OpenOptions::open`].1675 ///1676 /// # Examples1677 ///1678 /// ```no_run1679 /// #![feature(dirfd)]1680 /// use std::{fs::Dir, io};1681 ///1682 /// fn main() -> std::io::Result<()> {1683 /// let dir = Dir::open("foo")?;1684 /// let mut f = dir.open_file("bar.txt")?;1685 /// let contents = io::read_to_string(f)?;1686 /// assert_eq!(contents, "Hello, world!");1687 /// Ok(())1688 /// }1689 /// ```1690 #[unstable(feature = "dirfd", issue = "120426")]1691 pub fn open_file<P: AsRef<Path>>(&self, path: P) -> io::Result<File> {1692 self.inner1693 .open_file(path.as_ref(), &OpenOptions::new().read(true).0)1694 .map(|f| File { inner: f })1695 }16961697 /// Attempts to open a file according to `opts` relative to this directory.1698 ///1699 /// This function interprets `path` relative to the directory provided by `self`. To open a file1700 /// relative to the current working directory, or at an absolute path, see [`File::open`].1701 ///1702 /// # Errors1703 ///1704 /// This function will return an error if `path` does not point to an existing file.1705 /// Other errors may also be returned according to [`OpenOptions::open`].1706 ///1707 /// # Examples1708 ///1709 /// ```no_run1710 /// #![feature(dirfd)]1711 /// use std::{fs::{Dir, OpenOptions}, io::{self, Write}};1712 ///1713 /// fn main() -> io::Result<()> {1714 /// let dir = Dir::open("foo")?;1715 /// let mut opts = OpenOptions::new();1716 /// opts.read(true).write(true);1717 /// let mut f = dir.open_file_with("bar.txt", &opts)?;1718 /// f.write_all(b"Hello, world!")?;1719 /// let contents = io::read_to_string(f)?;1720 /// assert_eq!(contents, "Hello, world!");1721 /// Ok(())1722 /// }1723 /// ```1724 #[unstable(feature = "dirfd", issue = "120426")]1725 pub fn open_file_with<P: AsRef<Path>>(&self, path: P, opts: &OpenOptions) -> io::Result<File> {1726 self.inner.open_file(path.as_ref(), &opts.0).map(|f| File { inner: f })1727 }17281729 /// Attempts to remove a file relative to this directory.1730 ///1731 /// This function interprets `path` relative to the directory provided by `self`. To remove a file1732 /// relative to the current working directory, or at an absolute path, see [`fs::remove_file`][remove_file].1733 ///1734 /// # Errors1735 ///1736 /// This function will return an error if `path` does not point to an existing file.1737 /// Other errors may also be returned according to [`OpenOptions::open`].1738 ///1739 /// # Examples1740 ///1741 /// ```no_run1742 /// #![feature(dirfd)]1743 /// use std::fs::Dir;1744 ///1745 /// fn main() -> std::io::Result<()> {1746 /// let dir = Dir::open("foo")?;1747 /// dir.remove_file("bar.txt")?;1748 /// Ok(())1749 /// }1750 /// ```1751 #[unstable(feature = "dirfd", issue = "120426")]1752 pub fn remove_file<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {1753 self.inner.remove_file(path.as_ref())1754 }17551756 /// Attempts to rename a file or directory relative to this directory to a new name, replacing1757 /// the destination file if present.1758 ///1759 /// This function interprets `from` relative to the directory provided by `self` and `to` relative to the directory1760 /// provided by `to_dir`. To rename a file relative to the current working directory, or at an absolute path, see [`fs::rename`][rename].1761 ///1762 /// # Errors1763 ///1764 /// This function will return an error if `from` does not point to an existing file or directory.1765 /// Other errors may also be returned according to [`OpenOptions::open`].1766 ///1767 /// # Examples1768 ///1769 /// ```no_run1770 /// #![feature(dirfd)]1771 /// use std::fs::Dir;1772 ///1773 /// fn main() -> std::io::Result<()> {1774 /// let dir = Dir::open("foo")?;1775 /// dir.rename("bar.txt", &dir, "quux.txt")?;1776 /// Ok(())1777 /// }1778 /// ```1779 #[unstable(feature = "dirfd", issue = "120426")]1780 pub fn rename<P: AsRef<Path>, Q: AsRef<Path>>(1781 &self,1782 from: P,1783 to_dir: &Self,1784 to: Q,1785 ) -> io::Result<()> {1786 self.inner.rename(from.as_ref(), &to_dir.inner, to.as_ref())1787 }17881789 /// Attempts to create a directory relative to this directory.1790 ///1791 /// This function interprets `path` relative to the directory provided by `self`. To create a directory1792 /// relative to the current working directory, or at an absolute path, see1793 /// [`fs::create_dir`][crate::fs::create_dir].1794 #[unstable(feature = "dirfd", issue = "120426")]1795 pub fn create_dir<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {1796 self.inner.create_dir(path.as_ref())1797 }17981799 /// Attempts to open a directory in read-only mode relative to this directory.1800 ///1801 /// This function interprets `path` relative to the directory provided by `self`. To open a directory1802 /// relative to the current working directory, or at an absolute path, see [`Dir::open`].1803 ///1804 /// # Errors1805 ///1806 /// This function will return an error if `path` does not point to an existing directory.1807 /// Other errors may also be returned according to [`OpenOptions::open`].1808 ///1809 /// # Examples1810 ///1811 /// ```no_run1812 /// #![feature(dirfd)]1813 /// use std::{fs::Dir};1814 ///1815 /// fn main() -> std::io::Result<()> {1816 /// let dir = Dir::open("foo")?;1817 /// let foobar = dir.open_dir("bar")?;1818 /// Ok(())1819 /// }1820 /// ```1821 #[unstable(feature = "dirfd", issue = "120426")]1822 pub fn open_dir<P: AsRef<Path>>(&self, path: P) -> io::Result<Self> {1823 self.inner1824 .open_dir(path.as_ref(), &OpenOptions::new().read(true).0)1825 .map(|inner| Self { inner })1826 }18271828 /// Attempts to open a directory relative to this directory according to `opts`.1829 ///1830 /// This function interprets `path` relative to the directory provided by `self`. To open a directory1831 /// relative to the current working directory, or at an absolute path, see [`Dir::open`].1832 ///1833 /// # Errors1834 ///1835 /// This function will return errors according to [`OpenOptions::open`].1836 ///1837 /// # Examples1838 ///1839 /// ```no_run1840 /// #![feature(dirfd)]1841 /// use std::fs::{Dir, OpenOptions};1842 ///1843 /// fn main() -> std::io::Result<()> {1844 /// let dir = Dir::open("foo")?;1845 /// let foobar_w = dir.open_dir_with("bar", &OpenOptions::new().write(true))?;1846 /// Ok(())1847 /// }1848 /// ```1849 #[unstable(feature = "dirfd", issue = "120426")]1850 pub fn open_dir_with<P: AsRef<Path>>(&self, path: P, opts: &OpenOptions) -> io::Result<Self> {1851 self.inner.open_dir(path.as_ref(), &opts.0).map(|inner| Self { inner })1852 }18531854 /// Attempts to remove a directory relative to this directory.1855 ///1856 /// This function interprets `path` relative to the directory provided by `self`. To remove a directory1857 /// relative to the current working directory, or at an absolute path, see1858 /// [`fs::remove_dir`][crate::fs::remove_dir].1859 ///1860 /// # Errors1861 ///1862 /// This function will return an error if `path` does not point to an existing directory.1863 /// Other errors may also be returned according to [`OpenOptions::open`].1864 ///1865 /// # Examples1866 ///1867 /// ```no_run1868 /// #![feature(dirfd)]1869 /// use std::{fs::Dir};1870 ///1871 /// fn main() -> std::io::Result<()> {1872 /// let dir = Dir::open("foo")?;1873 /// dir.remove_dir("bar")?;1874 /// Ok(())1875 /// }1876 /// ```1877 #[unstable(feature = "dirfd", issue = "120426")]1878 pub fn remove_dir<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {1879 self.inner.remove_dir(path.as_ref())1880 }18811882 /// Creates a new `Dir` instance that shares the same underlying directory handle1883 /// as the existing `Dir` instance.1884 ///1885 /// # Examples1886 ///1887 /// Creates two handles for a directory named `foo`:1888 ///1889 /// ```no_run1890 /// #![feature(dirfd)]1891 /// use std::fs::Dir;1892 ///1893 /// fn main() -> std::io::Result<()> {1894 /// let dir = Dir::open("foo")?;1895 /// let dir_copy = dir.try_clone()?;1896 /// Ok(())1897 /// }1898 /// ```1899 #[unstable(feature = "dirfd", issue = "120426")]1900 pub fn try_clone(&self) -> io::Result<Self> {1901 Ok(Dir { inner: self.inner.duplicate()? })1902 }19031904 /// Queries the file system to get information about a file, directory, etc. relative to this1905 /// directory.1906 ///1907 /// This function will traverse symbolic links to query information about the destination file.1908 /// To query metadata about the path itself without following symbolic links, use1909 /// [`symlink_metadata`][Self::symlink_metadata].1910 ///1911 /// # Examples1912 ///1913 /// ```no_run1914 /// #![feature(dirfd)]1915 /// use std::fs::Dir;1916 ///1917 /// fn main() -> std::io::Result<()> {1918 /// let dir = Dir::open("foo")?;1919 /// let metadata = dir.metadata("subdir/file.txt")?;1920 /// Ok(())1921 /// }1922 /// ```1923 #[unstable(feature = "dirfd", issue = "120426")]1924 pub fn metadata<P: AsRef<Path>>(&self, path: P) -> io::Result<Metadata> {1925 self.inner.metadata(path.as_ref()).map(Metadata)1926 }19271928 /// Queries the file system to get information about a file, directory, etc. relative to this1929 /// directory.1930 ///1931 /// This function will return the [`Metadata`] of the exact path without traversing symbolic1932 /// links to a resolved destination file. Using this function on a path that is a file or1933 /// directory (not a symbolic link) will behave the same as [`metadata`][Self::metadata].1934 ///1935 /// # Examples1936 ///1937 /// ```no_run1938 /// #![feature(dirfd)]1939 /// use std::fs::Dir;1940 ///1941 /// fn main() -> std::io::Result<()> {1942 /// let dir = Dir::open("foo")?;1943 /// let metadata = dir.symlink_metadata("subdir/file.txt")?;1944 /// Ok(())1945 /// }1946 /// ```1947 #[unstable(feature = "dirfd", issue = "120426")]1948 pub fn symlink_metadata<P: AsRef<Path>>(&self, path: P) -> io::Result<Metadata> {1949 self.inner.symlink_metadata(path.as_ref()).map(Metadata)1950 }1951}19521953impl AsInner<fs_imp::Dir> for Dir {1954 #[inline]1955 fn as_inner(&self) -> &fs_imp::Dir {1956 &self.inner1957 }1958}1959impl FromInner<fs_imp::Dir> for Dir {1960 fn from_inner(f: fs_imp::Dir) -> Dir {1961 Dir { inner: f }1962 }1963}1964impl IntoInner<fs_imp::Dir> for Dir {1965 fn into_inner(self) -> fs_imp::Dir {1966 self.inner1967 }1968}19691970#[unstable(feature = "dirfd", issue = "120426")]1971impl fmt::Debug for Dir {1972 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {1973 self.inner.fmt(f)1974 }1975}19761977impl OpenOptions {1978 /// Creates a blank new set of options ready for configuration.1979 ///1980 /// All options are initially set to `false`.1981 ///1982 /// # Examples1983 ///1984 /// ```no_run1985 /// use std::fs::OpenOptions;1986 ///1987 /// let mut options = OpenOptions::new();1988 /// let file = options.read(true).open("foo.txt");1989 /// ```1990 #[cfg_attr(not(test), rustc_diagnostic_item = "open_options_new")]1991 #[stable(feature = "rust1", since = "1.0.0")]1992 #[must_use]1993 pub fn new() -> Self {1994 OpenOptions(fs_imp::OpenOptions::new())1995 }19961997 /// Sets the option for read access.1998 ///1999 /// This option, when true, will indicate that the file should be2000 /// `read`-able if opened.
Findings
✓ No findings reported for this file.