std/
fs.rs

1//! Filesystem manipulation operations.
2//!
3//! This module contains basic methods to manipulate the contents of the local
4//! filesystem. All methods in this module represent cross-platform filesystem
5//! operations. Extra platform-specific functionality can be found in the
6//! 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 changed
13//! 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 to
16//! 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 replaces
19//! the directory with a symbolic link between the check and the removal operation, the removal
20//! might affect the wrong location. This is why operations like [`remove_dir_all`] need to use
21//! 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 by
25//! 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.
28
29#![stable(feature = "rust1", since = "1.0.0")]
30#![deny(unsafe_op_in_unsafe_fn)]
31
32#[cfg(all(
33    test,
34    not(any(
35        target_os = "emscripten",
36        target_os = "wasi",
37        target_env = "sgx",
38        target_os = "xous",
39        target_os = "trusty",
40    ))
41))]
42mod tests;
43
44use crate::ffi::OsString;
45use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write};
46use crate::path::{Path, PathBuf};
47use crate::sealed::Sealed;
48use crate::sync::Arc;
49use crate::sys::fs as fs_imp;
50use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
51use crate::time::SystemTime;
52use crate::{error, fmt};
53
54/// An object providing access to an open file on the filesystem.
55///
56/// An instance of a `File` can be read and/or written depending on what options
57/// it was opened with. Files also implement [`Seek`] to alter the logical cursor
58/// that the file contains internally.
59///
60/// Files are automatically closed when they go out of scope.  Errors detected
61/// on closing are ignored by the implementation of `Drop`.  Use the method
62/// [`sync_all`] if these errors must be manually handled.
63///
64/// `File` does not buffer reads and writes. For efficiency, consider wrapping the
65/// file in a [`BufReader`] or [`BufWriter`] when performing many small [`read`]
66/// or [`write`] calls, unless unbuffered reads and writes are required.
67///
68/// # Examples
69///
70/// Creates a new file and write bytes to it (you can also use [`write`]):
71///
72/// ```no_run
73/// use std::fs::File;
74/// use std::io::prelude::*;
75///
76/// fn main() -> std::io::Result<()> {
77///     let mut file = File::create("foo.txt")?;
78///     file.write_all(b"Hello, world!")?;
79///     Ok(())
80/// }
81/// ```
82///
83/// Reads the contents of a file into a [`String`] (you can also use [`read`]):
84///
85/// ```no_run
86/// use std::fs::File;
87/// use std::io::prelude::*;
88///
89/// fn main() -> std::io::Result<()> {
90///     let mut file = File::open("foo.txt")?;
91///     let mut contents = String::new();
92///     file.read_to_string(&mut contents)?;
93///     assert_eq!(contents, "Hello, world!");
94///     Ok(())
95/// }
96/// ```
97///
98/// Using a buffered [`Read`]er:
99///
100/// ```no_run
101/// use std::fs::File;
102/// use std::io::BufReader;
103/// use std::io::prelude::*;
104///
105/// fn main() -> std::io::Result<()> {
106///     let file = File::open("foo.txt")?;
107///     let mut buf_reader = BufReader::new(file);
108///     let mut contents = String::new();
109///     buf_reader.read_to_string(&mut contents)?;
110///     assert_eq!(contents, "Hello, world!");
111///     Ok(())
112/// }
113/// ```
114///
115/// Note that, although read and write methods require a `&mut File`, because
116/// of the interfaces for [`Read`] and [`Write`], the holder of a `&File` can
117/// still modify the file, either through methods that take `&File` or by
118/// retrieving the underlying OS object and modifying the file that way.
119/// Additionally, many operating systems allow concurrent modification of files
120/// by different processes. Avoid assuming that holding a `&File` means that the
121/// file will not change.
122///
123/// # Platform-specific behavior
124///
125/// On Windows, the implementation of [`Read`] and [`Write`] traits for `File`
126/// perform synchronous I/O operations. Therefore the underlying file must not
127/// have been opened for asynchronous I/O (e.g. by using `FILE_FLAG_OVERLAPPED`).
128///
129/// [`BufReader`]: io::BufReader
130/// [`BufWriter`]: io::BufWriter
131/// [`sync_all`]: File::sync_all
132/// [`write`]: File::write
133/// [`read`]: File::read
134#[stable(feature = "rust1", since = "1.0.0")]
135#[cfg_attr(not(test), rustc_diagnostic_item = "File")]
136pub struct File {
137    inner: fs_imp::File,
138}
139
140/// An enumeration of possible errors which can occur while trying to acquire a lock
141/// from the [`try_lock`] method and [`try_lock_shared`] method on a [`File`].
142///
143/// [`try_lock`]: File::try_lock
144/// [`try_lock_shared`]: File::try_lock_shared
145#[stable(feature = "file_lock", since = "1.89.0")]
146pub enum TryLockError {
147    /// The lock could not be acquired due to an I/O error on the file. The standard library will
148    /// not return an [`ErrorKind::WouldBlock`] error inside [`TryLockError::Error`]
149    ///
150    /// [`ErrorKind::WouldBlock`]: io::ErrorKind::WouldBlock
151    Error(io::Error),
152    /// The lock could not be acquired at this time because it is held by another handle/process.
153    WouldBlock,
154}
155
156/// Metadata information about a file.
157///
158/// This structure is returned from the [`metadata`] or
159/// [`symlink_metadata`] function or method and represents known
160/// metadata about a file such as its permissions, size, modification
161/// times, etc.
162#[stable(feature = "rust1", since = "1.0.0")]
163#[derive(Clone)]
164pub struct Metadata(fs_imp::FileAttr);
165
166/// Iterator over the entries in a directory.
167///
168/// This iterator is returned from the [`read_dir`] function of this module and
169/// will yield instances of <code>[io::Result]<[DirEntry]></code>. Through a [`DirEntry`]
170/// information like the entry's path and possibly other metadata can be
171/// learned.
172///
173/// The order in which this iterator returns entries is platform and filesystem
174/// dependent.
175///
176/// # Errors
177/// This [`io::Result`] will be an [`Err`] if an error occurred while fetching
178/// the next entry from the OS.
179#[stable(feature = "rust1", since = "1.0.0")]
180#[derive(Debug)]
181pub struct ReadDir(fs_imp::ReadDir);
182
183/// Entries returned by the [`ReadDir`] iterator.
184///
185/// An instance of `DirEntry` represents an entry inside of a directory on the
186/// filesystem. Each entry can be inspected via methods to learn about the full
187/// path or possibly other metadata through per-platform extension traits.
188///
189/// # Platform-specific behavior
190///
191/// On Unix, the `DirEntry` struct contains an internal reference to the open
192/// directory. Holding `DirEntry` objects will consume a file handle even
193/// after the `ReadDir` iterator is dropped.
194///
195/// Note that this [may change in the future][changes].
196///
197/// [changes]: io#platform-specific-behavior
198#[stable(feature = "rust1", since = "1.0.0")]
199pub struct DirEntry(fs_imp::DirEntry);
200
201/// Options and flags which can be used to configure how a file is opened.
202///
203/// This builder exposes the ability to configure how a [`File`] is opened and
204/// what operations are permitted on the open file. The [`File::open`] and
205/// [`File::create`] methods are aliases for commonly used options using this
206/// builder.
207///
208/// Generally speaking, when using `OpenOptions`, you'll first call
209/// [`OpenOptions::new`], then chain calls to methods to set each option, then
210/// call [`OpenOptions::open`], passing the path of the file you're trying to
211/// open. This will give you a [`io::Result`] with a [`File`] inside that you
212/// can further operate on.
213///
214/// # Examples
215///
216/// Opening a file to read:
217///
218/// ```no_run
219/// use std::fs::OpenOptions;
220///
221/// let file = OpenOptions::new().read(true).open("foo.txt");
222/// ```
223///
224/// Opening a file for both reading and writing, as well as creating it if it
225/// doesn't exist:
226///
227/// ```no_run
228/// use std::fs::OpenOptions;
229///
230/// let file = OpenOptions::new()
231///             .read(true)
232///             .write(true)
233///             .create(true)
234///             .open("foo.txt");
235/// ```
236#[derive(Clone, Debug)]
237#[stable(feature = "rust1", since = "1.0.0")]
238#[cfg_attr(not(test), rustc_diagnostic_item = "FsOpenOptions")]
239pub struct OpenOptions(fs_imp::OpenOptions);
240
241/// Representation of the various timestamps on a file.
242#[derive(Copy, Clone, Debug, Default)]
243#[stable(feature = "file_set_times", since = "1.75.0")]
244pub struct FileTimes(fs_imp::FileTimes);
245
246/// Representation of the various permissions on a file.
247///
248/// This module only currently provides one bit of information,
249/// [`Permissions::readonly`], which is exposed on all currently supported
250/// platforms. Unix-specific functionality, such as mode bits, is available
251/// through the [`PermissionsExt`] trait.
252///
253/// [`PermissionsExt`]: crate::os::unix::fs::PermissionsExt
254#[derive(Clone, PartialEq, Eq, Debug)]
255#[stable(feature = "rust1", since = "1.0.0")]
256#[cfg_attr(not(test), rustc_diagnostic_item = "FsPermissions")]
257pub struct Permissions(fs_imp::FilePermissions);
258
259/// A structure representing a type of file with accessors for each file type.
260/// It is returned by [`Metadata::file_type`] method.
261#[stable(feature = "file_type", since = "1.1.0")]
262#[derive(Copy, Clone, PartialEq, Eq, Hash)]
263#[cfg_attr(not(test), rustc_diagnostic_item = "FileType")]
264pub struct FileType(fs_imp::FileType);
265
266/// A builder used to create directories in various manners.
267///
268/// This builder also supports platform-specific options.
269#[stable(feature = "dir_builder", since = "1.6.0")]
270#[cfg_attr(not(test), rustc_diagnostic_item = "DirBuilder")]
271#[derive(Debug)]
272pub struct DirBuilder {
273    inner: fs_imp::DirBuilder,
274    recursive: bool,
275}
276
277/// Reads the entire contents of a file into a bytes vector.
278///
279/// This is a convenience function for using [`File::open`] and [`read_to_end`]
280/// with fewer imports and without an intermediate variable.
281///
282/// [`read_to_end`]: Read::read_to_end
283///
284/// # Errors
285///
286/// This function will return an error if `path` does not already exist.
287/// Other errors may also be returned according to [`OpenOptions::open`].
288///
289/// While reading from the file, this function handles [`io::ErrorKind::Interrupted`]
290/// with automatic retries. See [io::Read] documentation for details.
291///
292/// # Examples
293///
294/// ```no_run
295/// use std::fs;
296///
297/// fn main() -> Result<(), Box<dyn std::error::Error + 'static>> {
298///     let data: Vec<u8> = fs::read("image.jpg")?;
299///     assert_eq!(data[0..3], [0xFF, 0xD8, 0xFF]);
300///     Ok(())
301/// }
302/// ```
303#[stable(feature = "fs_read_write_bytes", since = "1.26.0")]
304pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
305    fn inner(path: &Path) -> io::Result<Vec<u8>> {
306        let mut file = File::open(path)?;
307        let size = file.metadata().map(|m| m.len() as usize).ok();
308        let mut bytes = Vec::try_with_capacity(size.unwrap_or(0))?;
309        io::default_read_to_end(&mut file, &mut bytes, size)?;
310        Ok(bytes)
311    }
312    inner(path.as_ref())
313}
314
315/// Reads the entire contents of a file into a string.
316///
317/// This is a convenience function for using [`File::open`] and [`read_to_string`]
318/// with fewer imports and without an intermediate variable.
319///
320/// [`read_to_string`]: Read::read_to_string
321///
322/// # Errors
323///
324/// This function will return an error if `path` does not already exist.
325/// Other errors may also be returned according to [`OpenOptions::open`].
326///
327/// If the contents of the file are not valid UTF-8, then an error will also be
328/// returned.
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/// # Examples
334///
335/// ```no_run
336/// use std::fs;
337/// use std::error::Error;
338///
339/// fn main() -> Result<(), Box<dyn Error>> {
340///     let message: String = fs::read_to_string("message.txt")?;
341///     println!("{}", message);
342///     Ok(())
343/// }
344/// ```
345#[stable(feature = "fs_read_write", since = "1.26.0")]
346pub fn read_to_string<P: AsRef<Path>>(path: P) -> io::Result<String> {
347    fn inner(path: &Path) -> io::Result<String> {
348        let mut file = File::open(path)?;
349        let size = file.metadata().map(|m| m.len() as usize).ok();
350        let mut string = String::new();
351        string.try_reserve_exact(size.unwrap_or(0))?;
352        io::default_read_to_string(&mut file, &mut string, size)?;
353        Ok(string)
354    }
355    inner(path.as_ref())
356}
357
358/// Writes a slice as the entire contents of a file.
359///
360/// This function will create a file if it does not exist,
361/// and will entirely replace its contents if it does.
362///
363/// Depending on the platform, this function may fail if the
364/// full directory path does not exist.
365///
366/// This is a convenience function for using [`File::create`] and [`write_all`]
367/// with fewer imports.
368///
369/// [`write_all`]: Write::write_all
370///
371/// # Examples
372///
373/// ```no_run
374/// use std::fs;
375///
376/// fn main() -> std::io::Result<()> {
377///     fs::write("foo.txt", b"Lorem ipsum")?;
378///     fs::write("bar.txt", "dolor sit")?;
379///     Ok(())
380/// }
381/// ```
382#[stable(feature = "fs_read_write_bytes", since = "1.26.0")]
383pub fn write<P: AsRef<Path>, C: AsRef<[u8]>>(path: P, contents: C) -> io::Result<()> {
384    fn inner(path: &Path, contents: &[u8]) -> io::Result<()> {
385        File::create(path)?.write_all(contents)
386    }
387    inner(path.as_ref(), contents.as_ref())
388}
389
390#[stable(feature = "file_lock", since = "1.89.0")]
391impl error::Error for TryLockError {}
392
393#[stable(feature = "file_lock", since = "1.89.0")]
394impl fmt::Debug for TryLockError {
395    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
396        match self {
397            TryLockError::Error(err) => err.fmt(f),
398            TryLockError::WouldBlock => "WouldBlock".fmt(f),
399        }
400    }
401}
402
403#[stable(feature = "file_lock", since = "1.89.0")]
404impl fmt::Display for TryLockError {
405    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
406        match self {
407            TryLockError::Error(_) => "lock acquisition failed due to I/O error",
408            TryLockError::WouldBlock => "lock acquisition failed because the operation would block",
409        }
410        .fmt(f)
411    }
412}
413
414#[stable(feature = "file_lock", since = "1.89.0")]
415impl From<TryLockError> for io::Error {
416    fn from(err: TryLockError) -> io::Error {
417        match err {
418            TryLockError::Error(err) => err,
419            TryLockError::WouldBlock => io::ErrorKind::WouldBlock.into(),
420        }
421    }
422}
423
424impl File {
425    /// Attempts to open a file in read-only mode.
426    ///
427    /// See the [`OpenOptions::open`] method for more details.
428    ///
429    /// If you only need to read the entire file contents,
430    /// consider [`std::fs::read()`][self::read] or
431    /// [`std::fs::read_to_string()`][self::read_to_string] instead.
432    ///
433    /// # Errors
434    ///
435    /// This function will return an error if `path` does not already exist.
436    /// Other errors may also be returned according to [`OpenOptions::open`].
437    ///
438    /// # Examples
439    ///
440    /// ```no_run
441    /// use std::fs::File;
442    /// use std::io::Read;
443    ///
444    /// fn main() -> std::io::Result<()> {
445    ///     let mut f = File::open("foo.txt")?;
446    ///     let mut data = vec![];
447    ///     f.read_to_end(&mut data)?;
448    ///     Ok(())
449    /// }
450    /// ```
451    #[stable(feature = "rust1", since = "1.0.0")]
452    pub fn open<P: AsRef<Path>>(path: P) -> io::Result<File> {
453        OpenOptions::new().read(true).open(path.as_ref())
454    }
455
456    /// Attempts to open a file in read-only mode with buffering.
457    ///
458    /// See the [`OpenOptions::open`] method, the [`BufReader`][io::BufReader] type,
459    /// and the [`BufRead`][io::BufRead] trait for more details.
460    ///
461    /// If you only need to read the entire file contents,
462    /// consider [`std::fs::read()`][self::read] or
463    /// [`std::fs::read_to_string()`][self::read_to_string] instead.
464    ///
465    /// # Errors
466    ///
467    /// This function will return an error if `path` does not already exist,
468    /// or if memory allocation fails for the new buffer.
469    /// Other errors may also be returned according to [`OpenOptions::open`].
470    ///
471    /// # Examples
472    ///
473    /// ```no_run
474    /// #![feature(file_buffered)]
475    /// use std::fs::File;
476    /// use std::io::BufRead;
477    ///
478    /// fn main() -> std::io::Result<()> {
479    ///     let mut f = File::open_buffered("foo.txt")?;
480    ///     assert!(f.capacity() > 0);
481    ///     for (line, i) in f.lines().zip(1..) {
482    ///         println!("{i:6}: {}", line?);
483    ///     }
484    ///     Ok(())
485    /// }
486    /// ```
487    #[unstable(feature = "file_buffered", issue = "130804")]
488    pub fn open_buffered<P: AsRef<Path>>(path: P) -> io::Result<io::BufReader<File>> {
489        // Allocate the buffer *first* so we don't affect the filesystem otherwise.
490        let buffer = io::BufReader::<Self>::try_new_buffer()?;
491        let file = File::open(path)?;
492        Ok(io::BufReader::with_buffer(file, buffer))
493    }
494
495    /// Opens a file in write-only mode.
496    ///
497    /// This function will create a file if it does not exist,
498    /// and will truncate it if it does.
499    ///
500    /// Depending on the platform, this function may fail if the
501    /// full directory path does not exist.
502    /// See the [`OpenOptions::open`] function for more details.
503    ///
504    /// See also [`std::fs::write()`][self::write] for a simple function to
505    /// create a file with some given data.
506    ///
507    /// # Examples
508    ///
509    /// ```no_run
510    /// use std::fs::File;
511    /// use std::io::Write;
512    ///
513    /// fn main() -> std::io::Result<()> {
514    ///     let mut f = File::create("foo.txt")?;
515    ///     f.write_all(&1234_u32.to_be_bytes())?;
516    ///     Ok(())
517    /// }
518    /// ```
519    #[stable(feature = "rust1", since = "1.0.0")]
520    pub fn create<P: AsRef<Path>>(path: P) -> io::Result<File> {
521        OpenOptions::new().write(true).create(true).truncate(true).open(path.as_ref())
522    }
523
524    /// Opens a file in write-only mode with buffering.
525    ///
526    /// This function will create a file if it does not exist,
527    /// and will truncate it if it does.
528    ///
529    /// Depending on the platform, this function may fail if the
530    /// full directory path does not exist.
531    ///
532    /// See the [`OpenOptions::open`] method and the
533    /// [`BufWriter`][io::BufWriter] type for more details.
534    ///
535    /// See also [`std::fs::write()`][self::write] for a simple function to
536    /// create a file with some given data.
537    ///
538    /// # Examples
539    ///
540    /// ```no_run
541    /// #![feature(file_buffered)]
542    /// use std::fs::File;
543    /// use std::io::Write;
544    ///
545    /// fn main() -> std::io::Result<()> {
546    ///     let mut f = File::create_buffered("foo.txt")?;
547    ///     assert!(f.capacity() > 0);
548    ///     for i in 0..100 {
549    ///         writeln!(&mut f, "{i}")?;
550    ///     }
551    ///     f.flush()?;
552    ///     Ok(())
553    /// }
554    /// ```
555    #[unstable(feature = "file_buffered", issue = "130804")]
556    pub fn create_buffered<P: AsRef<Path>>(path: P) -> io::Result<io::BufWriter<File>> {
557        // Allocate the buffer *first* so we don't affect the filesystem otherwise.
558        let buffer = io::BufWriter::<Self>::try_new_buffer()?;
559        let file = File::create(path)?;
560        Ok(io::BufWriter::with_buffer(file, buffer))
561    }
562
563    /// Creates a new file in read-write mode; error if the file exists.
564    ///
565    /// This function will create a file if it does not exist, or return an error if it does. This
566    /// way, if the call succeeds, the file returned is guaranteed to be new.
567    /// If a file exists at the target location, creating a new file will fail with [`AlreadyExists`]
568    /// or another error based on the situation. See [`OpenOptions::open`] for a
569    /// non-exhaustive list of likely errors.
570    ///
571    /// This option is useful because it is atomic. Otherwise between checking whether a file
572    /// exists and creating a new one, the file may have been created by another process (a [TOCTOU]
573    /// race condition / attack).
574    ///
575    /// This can also be written using
576    /// `File::options().read(true).write(true).create_new(true).open(...)`.
577    ///
578    /// [`AlreadyExists`]: crate::io::ErrorKind::AlreadyExists
579    /// [TOCTOU]: self#time-of-check-to-time-of-use-toctou
580    ///
581    /// # Examples
582    ///
583    /// ```no_run
584    /// use std::fs::File;
585    /// use std::io::Write;
586    ///
587    /// fn main() -> std::io::Result<()> {
588    ///     let mut f = File::create_new("foo.txt")?;
589    ///     f.write_all("Hello, world!".as_bytes())?;
590    ///     Ok(())
591    /// }
592    /// ```
593    #[stable(feature = "file_create_new", since = "1.77.0")]
594    pub fn create_new<P: AsRef<Path>>(path: P) -> io::Result<File> {
595        OpenOptions::new().read(true).write(true).create_new(true).open(path.as_ref())
596    }
597
598    /// Returns a new OpenOptions object.
599    ///
600    /// This function returns a new OpenOptions object that you can use to
601    /// open or create a file with specific options if `open()` or `create()`
602    /// are not appropriate.
603    ///
604    /// It is equivalent to `OpenOptions::new()`, but allows you to write more
605    /// readable code. Instead of
606    /// `OpenOptions::new().append(true).open("example.log")`,
607    /// you can write `File::options().append(true).open("example.log")`. This
608    /// also avoids the need to import `OpenOptions`.
609    ///
610    /// See the [`OpenOptions::new`] function for more details.
611    ///
612    /// # Examples
613    ///
614    /// ```no_run
615    /// use std::fs::File;
616    /// use std::io::Write;
617    ///
618    /// fn main() -> std::io::Result<()> {
619    ///     let mut f = File::options().append(true).open("example.log")?;
620    ///     writeln!(&mut f, "new line")?;
621    ///     Ok(())
622    /// }
623    /// ```
624    #[must_use]
625    #[stable(feature = "with_options", since = "1.58.0")]
626    #[cfg_attr(not(test), rustc_diagnostic_item = "file_options")]
627    pub fn options() -> OpenOptions {
628        OpenOptions::new()
629    }
630
631    /// Attempts to sync all OS-internal file content and metadata to disk.
632    ///
633    /// This function will attempt to ensure that all in-memory data reaches the
634    /// filesystem before returning.
635    ///
636    /// This can be used to handle errors that would otherwise only be caught
637    /// when the `File` is closed, as dropping a `File` will ignore all errors.
638    /// Note, however, that `sync_all` is generally more expensive than closing
639    /// a file by dropping it, because the latter is not required to block until
640    /// the data has been written to the filesystem.
641    ///
642    /// If synchronizing the metadata is not required, use [`sync_data`] instead.
643    ///
644    /// [`sync_data`]: File::sync_data
645    ///
646    /// # Examples
647    ///
648    /// ```no_run
649    /// use std::fs::File;
650    /// use std::io::prelude::*;
651    ///
652    /// fn main() -> std::io::Result<()> {
653    ///     let mut f = File::create("foo.txt")?;
654    ///     f.write_all(b"Hello, world!")?;
655    ///
656    ///     f.sync_all()?;
657    ///     Ok(())
658    /// }
659    /// ```
660    #[stable(feature = "rust1", since = "1.0.0")]
661    #[doc(alias = "fsync")]
662    pub fn sync_all(&self) -> io::Result<()> {
663        self.inner.fsync()
664    }
665
666    /// This function is similar to [`sync_all`], except that it might not
667    /// synchronize file metadata to the filesystem.
668    ///
669    /// This is intended for use cases that must synchronize content, but don't
670    /// need the metadata on disk. The goal of this method is to reduce disk
671    /// operations.
672    ///
673    /// Note that some platforms may simply implement this in terms of
674    /// [`sync_all`].
675    ///
676    /// [`sync_all`]: File::sync_all
677    ///
678    /// # Examples
679    ///
680    /// ```no_run
681    /// use std::fs::File;
682    /// use std::io::prelude::*;
683    ///
684    /// fn main() -> std::io::Result<()> {
685    ///     let mut f = File::create("foo.txt")?;
686    ///     f.write_all(b"Hello, world!")?;
687    ///
688    ///     f.sync_data()?;
689    ///     Ok(())
690    /// }
691    /// ```
692    #[stable(feature = "rust1", since = "1.0.0")]
693    #[doc(alias = "fdatasync")]
694    pub fn sync_data(&self) -> io::Result<()> {
695        self.inner.datasync()
696    }
697
698    /// Acquire an exclusive lock on the file. Blocks until the lock can be acquired.
699    ///
700    /// This acquires an exclusive lock; no other file handle to this file may acquire another lock.
701    ///
702    /// This lock may be advisory or mandatory. This lock is meant to interact with [`lock`],
703    /// [`try_lock`], [`lock_shared`], [`try_lock_shared`], and [`unlock`]. Its interactions with
704    /// other methods, such as [`read`] and [`write`] are platform specific, and it may or may not
705    /// cause non-lockholders to block.
706    ///
707    /// If this file handle/descriptor, or a clone of it, already holds a lock the exact behavior
708    /// is unspecified and platform dependent, including the possibility that it will deadlock.
709    /// However, if this method returns, then an exclusive lock is held.
710    ///
711    /// If the file is not open for writing, it is unspecified whether this function returns an error.
712    ///
713    /// The lock will be released when this file (along with any other file descriptors/handles
714    /// duplicated or inherited from it) is closed, or if the [`unlock`] method is called.
715    ///
716    /// # Platform-specific behavior
717    ///
718    /// This function currently corresponds to the `flock` function on Unix with the `LOCK_EX` flag,
719    /// and the `LockFileEx` function on Windows with the `LOCKFILE_EXCLUSIVE_LOCK` flag. Note that,
720    /// this [may change in the future][changes].
721    ///
722    /// On Windows, locking a file will fail if the file is opened only for append. To lock a file,
723    /// open it with one of `.read(true)`, `.read(true).append(true)`, or `.write(true)`.
724    ///
725    /// [changes]: io#platform-specific-behavior
726    ///
727    /// [`lock`]: File::lock
728    /// [`lock_shared`]: File::lock_shared
729    /// [`try_lock`]: File::try_lock
730    /// [`try_lock_shared`]: File::try_lock_shared
731    /// [`unlock`]: File::unlock
732    /// [`read`]: Read::read
733    /// [`write`]: Write::write
734    ///
735    /// # Examples
736    ///
737    /// ```no_run
738    /// use std::fs::File;
739    ///
740    /// fn main() -> std::io::Result<()> {
741    ///     let f = File::create("foo.txt")?;
742    ///     f.lock()?;
743    ///     Ok(())
744    /// }
745    /// ```
746    #[stable(feature = "file_lock", since = "1.89.0")]
747    pub fn lock(&self) -> io::Result<()> {
748        self.inner.lock()
749    }
750
751    /// Acquire a shared (non-exclusive) lock on the file. Blocks until the lock can be acquired.
752    ///
753    /// This acquires a shared lock; more than one file handle may hold a shared lock, but none may
754    /// hold an exclusive lock at the same time.
755    ///
756    /// This lock may be advisory or mandatory. This lock is meant to interact with [`lock`],
757    /// [`try_lock`], [`lock_shared`], [`try_lock_shared`], and [`unlock`]. Its interactions with
758    /// other methods, such as [`read`] and [`write`] are platform specific, and it may or may not
759    /// cause non-lockholders to block.
760    ///
761    /// If this file handle/descriptor, or a clone of it, already holds a lock, the exact behavior
762    /// is unspecified and platform dependent, including the possibility that it will deadlock.
763    /// However, if this method returns, then a shared lock is held.
764    ///
765    /// The lock will be released when this file (along with any other file descriptors/handles
766    /// duplicated or inherited from it) is closed, or if the [`unlock`] method is called.
767    ///
768    /// # Platform-specific behavior
769    ///
770    /// This function currently corresponds to the `flock` function on Unix with the `LOCK_SH` flag,
771    /// and the `LockFileEx` function on Windows. Note that, this
772    /// [may change in the future][changes].
773    ///
774    /// On Windows, locking a file will fail if the file is opened only for append. To lock a file,
775    /// open it with one of `.read(true)`, `.read(true).append(true)`, or `.write(true)`.
776    ///
777    /// [changes]: io#platform-specific-behavior
778    ///
779    /// [`lock`]: File::lock
780    /// [`lock_shared`]: File::lock_shared
781    /// [`try_lock`]: File::try_lock
782    /// [`try_lock_shared`]: File::try_lock_shared
783    /// [`unlock`]: File::unlock
784    /// [`read`]: Read::read
785    /// [`write`]: Write::write
786    ///
787    /// # Examples
788    ///
789    /// ```no_run
790    /// use std::fs::File;
791    ///
792    /// fn main() -> std::io::Result<()> {
793    ///     let f = File::open("foo.txt")?;
794    ///     f.lock_shared()?;
795    ///     Ok(())
796    /// }
797    /// ```
798    #[stable(feature = "file_lock", since = "1.89.0")]
799    pub fn lock_shared(&self) -> io::Result<()> {
800        self.inner.lock_shared()
801    }
802
803    /// Try to acquire an exclusive lock on the file.
804    ///
805    /// Returns `Err(TryLockError::WouldBlock)` if a different lock is already held on this file
806    /// (via another handle/descriptor).
807    ///
808    /// This acquires an exclusive lock; no other file handle to this file may acquire another lock.
809    ///
810    /// This lock may be advisory or mandatory. This lock is meant to interact with [`lock`],
811    /// [`try_lock`], [`lock_shared`], [`try_lock_shared`], and [`unlock`]. Its interactions with
812    /// other methods, such as [`read`] and [`write`] are platform specific, and it may or may not
813    /// cause non-lockholders to block.
814    ///
815    /// If this file handle/descriptor, or a clone of it, already holds a lock, the exact behavior
816    /// is unspecified and platform dependent, including the possibility that it will deadlock.
817    /// However, if this method returns `Ok(true)`, then it has acquired an exclusive lock.
818    ///
819    /// If the file is not open for writing, it is unspecified whether this function returns an error.
820    ///
821    /// The lock will be released when this file (along with any other file descriptors/handles
822    /// duplicated or inherited from it) is closed, or if the [`unlock`] method is called.
823    ///
824    /// # Platform-specific behavior
825    ///
826    /// This function currently corresponds to the `flock` function on Unix with the `LOCK_EX` and
827    /// `LOCK_NB` flags, and the `LockFileEx` function on Windows with the `LOCKFILE_EXCLUSIVE_LOCK`
828    /// and `LOCKFILE_FAIL_IMMEDIATELY` flags. Note that, this
829    /// [may change in the future][changes].
830    ///
831    /// On Windows, locking a file will fail if the file is opened only for append. To lock a file,
832    /// open it with one of `.read(true)`, `.read(true).append(true)`, or `.write(true)`.
833    ///
834    /// [changes]: io#platform-specific-behavior
835    ///
836    /// [`lock`]: File::lock
837    /// [`lock_shared`]: File::lock_shared
838    /// [`try_lock`]: File::try_lock
839    /// [`try_lock_shared`]: File::try_lock_shared
840    /// [`unlock`]: File::unlock
841    /// [`read`]: Read::read
842    /// [`write`]: Write::write
843    ///
844    /// # Examples
845    ///
846    /// ```no_run
847    /// use std::fs::{File, TryLockError};
848    ///
849    /// fn main() -> std::io::Result<()> {
850    ///     let f = File::create("foo.txt")?;
851    ///     // Explicit handling of the WouldBlock error
852    ///     match f.try_lock() {
853    ///         Ok(_) => (),
854    ///         Err(TryLockError::WouldBlock) => (), // Lock not acquired
855    ///         Err(TryLockError::Error(err)) => return Err(err),
856    ///     }
857    ///     // Alternately, propagate the error as an io::Error
858    ///     f.try_lock()?;
859    ///     Ok(())
860    /// }
861    /// ```
862    #[stable(feature = "file_lock", since = "1.89.0")]
863    pub fn try_lock(&self) -> Result<(), TryLockError> {
864        self.inner.try_lock()
865    }
866
867    /// Try to acquire a shared (non-exclusive) lock on the file.
868    ///
869    /// Returns `Err(TryLockError::WouldBlock)` if a different lock is already held on this file
870    /// (via another handle/descriptor).
871    ///
872    /// This acquires a shared lock; more than one file handle may hold a shared lock, but none may
873    /// hold an exclusive lock at the same time.
874    ///
875    /// This lock may be advisory or mandatory. This lock is meant to interact with [`lock`],
876    /// [`try_lock`], [`lock_shared`], [`try_lock_shared`], and [`unlock`]. Its interactions with
877    /// other methods, such as [`read`] and [`write`] are platform specific, and it may or may not
878    /// cause non-lockholders to block.
879    ///
880    /// If this file handle, or a clone of it, already holds a lock, the exact behavior is
881    /// unspecified and platform dependent, including the possibility that it will deadlock.
882    /// However, if this method returns `Ok(true)`, then it has acquired a shared lock.
883    ///
884    /// The lock will be released when this file (along with any other file descriptors/handles
885    /// duplicated or inherited from it) is closed, or if the [`unlock`] method is called.
886    ///
887    /// # Platform-specific behavior
888    ///
889    /// This function currently corresponds to the `flock` function on Unix with the `LOCK_SH` and
890    /// `LOCK_NB` flags, and the `LockFileEx` function on Windows with the
891    /// `LOCKFILE_FAIL_IMMEDIATELY` flag. Note that, this
892    /// [may change in the future][changes].
893    ///
894    /// On Windows, locking a file will fail if the file is opened only for append. To lock a file,
895    /// open it with one of `.read(true)`, `.read(true).append(true)`, or `.write(true)`.
896    ///
897    /// [changes]: io#platform-specific-behavior
898    ///
899    /// [`lock`]: File::lock
900    /// [`lock_shared`]: File::lock_shared
901    /// [`try_lock`]: File::try_lock
902    /// [`try_lock_shared`]: File::try_lock_shared
903    /// [`unlock`]: File::unlock
904    /// [`read`]: Read::read
905    /// [`write`]: Write::write
906    ///
907    /// # Examples
908    ///
909    /// ```no_run
910    /// use std::fs::{File, TryLockError};
911    ///
912    /// fn main() -> std::io::Result<()> {
913    ///     let f = File::open("foo.txt")?;
914    ///     // Explicit handling of the WouldBlock error
915    ///     match f.try_lock_shared() {
916    ///         Ok(_) => (),
917    ///         Err(TryLockError::WouldBlock) => (), // Lock not acquired
918    ///         Err(TryLockError::Error(err)) => return Err(err),
919    ///     }
920    ///     // Alternately, propagate the error as an io::Error
921    ///     f.try_lock_shared()?;
922    ///
923    ///     Ok(())
924    /// }
925    /// ```
926    #[stable(feature = "file_lock", since = "1.89.0")]
927    pub fn try_lock_shared(&self) -> Result<(), TryLockError> {
928        self.inner.try_lock_shared()
929    }
930
931    /// Release all locks on the file.
932    ///
933    /// All locks are released when the file (along with any other file descriptors/handles
934    /// duplicated or inherited from it) is closed. This method allows releasing locks without
935    /// closing the file.
936    ///
937    /// If no lock is currently held via this file descriptor/handle, this method may return an
938    /// error, or may return successfully without taking any action.
939    ///
940    /// # Platform-specific behavior
941    ///
942    /// This function currently corresponds to the `flock` function on Unix with the `LOCK_UN` flag,
943    /// and the `UnlockFile` function on Windows. Note that, this
944    /// [may change in the future][changes].
945    ///
946    /// On Windows, locking a file will fail if the file is opened only for append. To lock a file,
947    /// open it with one of `.read(true)`, `.read(true).append(true)`, or `.write(true)`.
948    ///
949    /// [changes]: io#platform-specific-behavior
950    ///
951    /// # Examples
952    ///
953    /// ```no_run
954    /// use std::fs::File;
955    ///
956    /// fn main() -> std::io::Result<()> {
957    ///     let f = File::open("foo.txt")?;
958    ///     f.lock()?;
959    ///     f.unlock()?;
960    ///     Ok(())
961    /// }
962    /// ```
963    #[stable(feature = "file_lock", since = "1.89.0")]
964    pub fn unlock(&self) -> io::Result<()> {
965        self.inner.unlock()
966    }
967
968    /// Truncates or extends the underlying file, updating the size of
969    /// this file to become `size`.
970    ///
971    /// If the `size` is less than the current file's size, then the file will
972    /// be shrunk. If it is greater than the current file's size, then the file
973    /// will be extended to `size` and have all of the intermediate data filled
974    /// in with 0s.
975    ///
976    /// The file's cursor isn't changed. In particular, if the cursor was at the
977    /// end and the file is shrunk using this operation, the cursor will now be
978    /// past the end.
979    ///
980    /// # Errors
981    ///
982    /// This function will return an error if the file is not opened for writing.
983    /// Also, [`std::io::ErrorKind::InvalidInput`](crate::io::ErrorKind::InvalidInput)
984    /// will be returned if the desired length would cause an overflow due to
985    /// the implementation specifics.
986    ///
987    /// # Examples
988    ///
989    /// ```no_run
990    /// use std::fs::File;
991    ///
992    /// fn main() -> std::io::Result<()> {
993    ///     let mut f = File::create("foo.txt")?;
994    ///     f.set_len(10)?;
995    ///     Ok(())
996    /// }
997    /// ```
998    ///
999    /// Note that this method alters the content of the underlying file, even
1000    /// though it takes `&self` rather than `&mut self`.
1001    #[stable(feature = "rust1", since = "1.0.0")]
1002    pub fn set_len(&self, size: u64) -> io::Result<()> {
1003        self.inner.truncate(size)
1004    }
1005
1006    /// Queries metadata about the underlying file.
1007    ///
1008    /// # Examples
1009    ///
1010    /// ```no_run
1011    /// use std::fs::File;
1012    ///
1013    /// fn main() -> std::io::Result<()> {
1014    ///     let mut f = File::open("foo.txt")?;
1015    ///     let metadata = f.metadata()?;
1016    ///     Ok(())
1017    /// }
1018    /// ```
1019    #[stable(feature = "rust1", since = "1.0.0")]
1020    pub fn metadata(&self) -> io::Result<Metadata> {
1021        self.inner.file_attr().map(Metadata)
1022    }
1023
1024    /// Creates a new `File` instance that shares the same underlying file handle
1025    /// as the existing `File` instance. Reads, writes, and seeks will affect
1026    /// both `File` instances simultaneously.
1027    ///
1028    /// # Examples
1029    ///
1030    /// Creates two handles for a file named `foo.txt`:
1031    ///
1032    /// ```no_run
1033    /// use std::fs::File;
1034    ///
1035    /// fn main() -> std::io::Result<()> {
1036    ///     let mut file = File::open("foo.txt")?;
1037    ///     let file_copy = file.try_clone()?;
1038    ///     Ok(())
1039    /// }
1040    /// ```
1041    ///
1042    /// Assuming there’s a file named `foo.txt` with contents `abcdef\n`, create
1043    /// two handles, seek one of them, and read the remaining bytes from the
1044    /// other handle:
1045    ///
1046    /// ```no_run
1047    /// use std::fs::File;
1048    /// use std::io::SeekFrom;
1049    /// use std::io::prelude::*;
1050    ///
1051    /// fn main() -> std::io::Result<()> {
1052    ///     let mut file = File::open("foo.txt")?;
1053    ///     let mut file_copy = file.try_clone()?;
1054    ///
1055    ///     file.seek(SeekFrom::Start(3))?;
1056    ///
1057    ///     let mut contents = vec![];
1058    ///     file_copy.read_to_end(&mut contents)?;
1059    ///     assert_eq!(contents, b"def\n");
1060    ///     Ok(())
1061    /// }
1062    /// ```
1063    #[stable(feature = "file_try_clone", since = "1.9.0")]
1064    pub fn try_clone(&self) -> io::Result<File> {
1065        Ok(File { inner: self.inner.duplicate()? })
1066    }
1067
1068    /// Changes the permissions on the underlying file.
1069    ///
1070    /// # Platform-specific behavior
1071    ///
1072    /// This function currently corresponds to the `fchmod` function on Unix and
1073    /// the `SetFileInformationByHandle` function on Windows. Note that, this
1074    /// [may change in the future][changes].
1075    ///
1076    /// [changes]: io#platform-specific-behavior
1077    ///
1078    /// # Errors
1079    ///
1080    /// This function will return an error if the user lacks permission change
1081    /// attributes on the underlying file. It may also return an error in other
1082    /// os-specific unspecified cases.
1083    ///
1084    /// # Examples
1085    ///
1086    /// ```no_run
1087    /// fn main() -> std::io::Result<()> {
1088    ///     use std::fs::File;
1089    ///
1090    ///     let file = File::open("foo.txt")?;
1091    ///     let mut perms = file.metadata()?.permissions();
1092    ///     perms.set_readonly(true);
1093    ///     file.set_permissions(perms)?;
1094    ///     Ok(())
1095    /// }
1096    /// ```
1097    ///
1098    /// Note that this method alters the permissions of the underlying file,
1099    /// even though it takes `&self` rather than `&mut self`.
1100    #[doc(alias = "fchmod", alias = "SetFileInformationByHandle")]
1101    #[stable(feature = "set_permissions_atomic", since = "1.16.0")]
1102    pub fn set_permissions(&self, perm: Permissions) -> io::Result<()> {
1103        self.inner.set_permissions(perm.0)
1104    }
1105
1106    /// Changes the timestamps of the underlying file.
1107    ///
1108    /// # Platform-specific behavior
1109    ///
1110    /// This function currently corresponds to the `futimens` function on Unix (falling back to
1111    /// `futimes` on macOS before 10.13) and the `SetFileTime` function on Windows. Note that this
1112    /// [may change in the future][changes].
1113    ///
1114    /// [changes]: io#platform-specific-behavior
1115    ///
1116    /// # Errors
1117    ///
1118    /// This function will return an error if the user lacks permission to change timestamps on the
1119    /// underlying file. It may also return an error in other os-specific unspecified cases.
1120    ///
1121    /// This function may return an error if the operating system lacks support to change one or
1122    /// more of the timestamps set in the `FileTimes` structure.
1123    ///
1124    /// # Examples
1125    ///
1126    /// ```no_run
1127    /// fn main() -> std::io::Result<()> {
1128    ///     use std::fs::{self, File, FileTimes};
1129    ///
1130    ///     let src = fs::metadata("src")?;
1131    ///     let dest = File::options().write(true).open("dest")?;
1132    ///     let times = FileTimes::new()
1133    ///         .set_accessed(src.accessed()?)
1134    ///         .set_modified(src.modified()?);
1135    ///     dest.set_times(times)?;
1136    ///     Ok(())
1137    /// }
1138    /// ```
1139    #[stable(feature = "file_set_times", since = "1.75.0")]
1140    #[doc(alias = "futimens")]
1141    #[doc(alias = "futimes")]
1142    #[doc(alias = "SetFileTime")]
1143    pub fn set_times(&self, times: FileTimes) -> io::Result<()> {
1144        self.inner.set_times(times.0)
1145    }
1146
1147    /// Changes the modification time of the underlying file.
1148    ///
1149    /// This is an alias for `set_times(FileTimes::new().set_modified(time))`.
1150    #[stable(feature = "file_set_times", since = "1.75.0")]
1151    #[inline]
1152    pub fn set_modified(&self, time: SystemTime) -> io::Result<()> {
1153        self.set_times(FileTimes::new().set_modified(time))
1154    }
1155}
1156
1157// In addition to the `impl`s here, `File` also has `impl`s for
1158// `AsFd`/`From<OwnedFd>`/`Into<OwnedFd>` and
1159// `AsRawFd`/`IntoRawFd`/`FromRawFd`, on Unix and WASI, and
1160// `AsHandle`/`From<OwnedHandle>`/`Into<OwnedHandle>` and
1161// `AsRawHandle`/`IntoRawHandle`/`FromRawHandle` on Windows.
1162
1163impl AsInner<fs_imp::File> for File {
1164    #[inline]
1165    fn as_inner(&self) -> &fs_imp::File {
1166        &self.inner
1167    }
1168}
1169impl FromInner<fs_imp::File> for File {
1170    fn from_inner(f: fs_imp::File) -> File {
1171        File { inner: f }
1172    }
1173}
1174impl IntoInner<fs_imp::File> for File {
1175    fn into_inner(self) -> fs_imp::File {
1176        self.inner
1177    }
1178}
1179
1180#[stable(feature = "rust1", since = "1.0.0")]
1181impl fmt::Debug for File {
1182    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1183        self.inner.fmt(f)
1184    }
1185}
1186
1187/// Indicates how much extra capacity is needed to read the rest of the file.
1188fn buffer_capacity_required(mut file: &File) -> Option<usize> {
1189    let size = file.metadata().map(|m| m.len()).ok()?;
1190    let pos = file.stream_position().ok()?;
1191    // Don't worry about `usize` overflow because reading will fail regardless
1192    // in that case.
1193    Some(size.saturating_sub(pos) as usize)
1194}
1195
1196#[stable(feature = "rust1", since = "1.0.0")]
1197impl Read for &File {
1198    /// Reads some bytes from the file.
1199    ///
1200    /// See [`Read::read`] docs for more info.
1201    ///
1202    /// # Platform-specific behavior
1203    ///
1204    /// This function currently corresponds to the `read` function on Unix and
1205    /// the `NtReadFile` function on Windows. Note that this [may change in
1206    /// the future][changes].
1207    ///
1208    /// [changes]: io#platform-specific-behavior
1209    #[inline]
1210    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
1211        self.inner.read(buf)
1212    }
1213
1214    /// Like `read`, except that it reads into a slice of buffers.
1215    ///
1216    /// See [`Read::read_vectored`] docs for more info.
1217    ///
1218    /// # Platform-specific behavior
1219    ///
1220    /// This function currently corresponds to the `readv` function on Unix and
1221    /// falls back to the `read` implementation on Windows. Note that this
1222    /// [may change in the future][changes].
1223    ///
1224    /// [changes]: io#platform-specific-behavior
1225    #[inline]
1226    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
1227        self.inner.read_vectored(bufs)
1228    }
1229
1230    #[inline]
1231    fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
1232        self.inner.read_buf(cursor)
1233    }
1234
1235    /// Determines if `File` has an efficient `read_vectored` implementation.
1236    ///
1237    /// See [`Read::is_read_vectored`] docs for more info.
1238    ///
1239    /// # Platform-specific behavior
1240    ///
1241    /// This function currently returns `true` on Unix an `false` on Windows.
1242    /// Note that this [may change in the future][changes].
1243    ///
1244    /// [changes]: io#platform-specific-behavior
1245    #[inline]
1246    fn is_read_vectored(&self) -> bool {
1247        self.inner.is_read_vectored()
1248    }
1249
1250    // Reserves space in the buffer based on the file size when available.
1251    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
1252        let size = buffer_capacity_required(self);
1253        buf.try_reserve(size.unwrap_or(0))?;
1254        io::default_read_to_end(self, buf, size)
1255    }
1256
1257    // Reserves space in the buffer based on the file size when available.
1258    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
1259        let size = buffer_capacity_required(self);
1260        buf.try_reserve(size.unwrap_or(0))?;
1261        io::default_read_to_string(self, buf, size)
1262    }
1263}
1264#[stable(feature = "rust1", since = "1.0.0")]
1265impl Write for &File {
1266    /// Writes some bytes to the file.
1267    ///
1268    /// See [`Write::write`] docs for more info.
1269    ///
1270    /// # Platform-specific behavior
1271    ///
1272    /// This function currently corresponds to the `write` function on Unix and
1273    /// the `NtWriteFile` function on Windows. Note that this [may change in
1274    /// the future][changes].
1275    ///
1276    /// [changes]: io#platform-specific-behavior
1277    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
1278        self.inner.write(buf)
1279    }
1280
1281    /// Like `write`, except that it writes into a slice of buffers.
1282    ///
1283    /// See [`Write::write_vectored`] docs for more info.
1284    ///
1285    /// # Platform-specific behavior
1286    ///
1287    /// This function currently corresponds to the `writev` function on Unix
1288    /// and falls back to the `write` implementation on Windows. Note that this
1289    /// [may change in the future][changes].
1290    ///
1291    /// [changes]: io#platform-specific-behavior
1292    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
1293        self.inner.write_vectored(bufs)
1294    }
1295
1296    /// Determines if `File` has an efficient `write_vectored` implementation.
1297    ///
1298    /// See [`Write::is_write_vectored`] docs for more info.
1299    ///
1300    /// # Platform-specific behavior
1301    ///
1302    /// This function currently returns `true` on Unix an `false` on Windows.
1303    /// Note that this [may change in the future][changes].
1304    ///
1305    /// [changes]: io#platform-specific-behavior
1306    #[inline]
1307    fn is_write_vectored(&self) -> bool {
1308        self.inner.is_write_vectored()
1309    }
1310
1311    /// Flushes the file, ensuring that all intermediately buffered contents
1312    /// reach their destination.
1313    ///
1314    /// See [`Write::flush`] docs for more info.
1315    ///
1316    /// # Platform-specific behavior
1317    ///
1318    /// Since a `File` structure doesn't contain any buffers, this function is
1319    /// currently a no-op on Unix and Windows. Note that this [may change in
1320    /// the future][changes].
1321    ///
1322    /// [changes]: io#platform-specific-behavior
1323    #[inline]
1324    fn flush(&mut self) -> io::Result<()> {
1325        self.inner.flush()
1326    }
1327}
1328#[stable(feature = "rust1", since = "1.0.0")]
1329impl Seek for &File {
1330    /// Seek to an offset, in bytes in a file.
1331    ///
1332    /// See [`Seek::seek`] docs for more info.
1333    ///
1334    /// # Platform-specific behavior
1335    ///
1336    /// This function currently corresponds to the `lseek64` function on Unix
1337    /// and the `SetFilePointerEx` function on Windows. Note that this [may
1338    /// change in the future][changes].
1339    ///
1340    /// [changes]: io#platform-specific-behavior
1341    fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
1342        self.inner.seek(pos)
1343    }
1344
1345    /// Returns the length of this file (in bytes).
1346    ///
1347    /// See [`Seek::stream_len`] docs for more info.
1348    ///
1349    /// # Platform-specific behavior
1350    ///
1351    /// This function currently corresponds to the `statx` function on Linux
1352    /// (with fallbacks) and the `GetFileSizeEx` function on Windows. Note that
1353    /// this [may change in the future][changes].
1354    ///
1355    /// [changes]: io#platform-specific-behavior
1356    fn stream_len(&mut self) -> io::Result<u64> {
1357        if let Some(result) = self.inner.size() {
1358            return result;
1359        }
1360        io::stream_len_default(self)
1361    }
1362
1363    fn stream_position(&mut self) -> io::Result<u64> {
1364        self.inner.tell()
1365    }
1366}
1367
1368#[stable(feature = "rust1", since = "1.0.0")]
1369impl Read for File {
1370    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
1371        (&*self).read(buf)
1372    }
1373    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
1374        (&*self).read_vectored(bufs)
1375    }
1376    fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
1377        (&*self).read_buf(cursor)
1378    }
1379    #[inline]
1380    fn is_read_vectored(&self) -> bool {
1381        (&&*self).is_read_vectored()
1382    }
1383    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
1384        (&*self).read_to_end(buf)
1385    }
1386    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
1387        (&*self).read_to_string(buf)
1388    }
1389}
1390#[stable(feature = "rust1", since = "1.0.0")]
1391impl Write for File {
1392    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
1393        (&*self).write(buf)
1394    }
1395    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
1396        (&*self).write_vectored(bufs)
1397    }
1398    #[inline]
1399    fn is_write_vectored(&self) -> bool {
1400        (&&*self).is_write_vectored()
1401    }
1402    #[inline]
1403    fn flush(&mut self) -> io::Result<()> {
1404        (&*self).flush()
1405    }
1406}
1407#[stable(feature = "rust1", since = "1.0.0")]
1408impl Seek for File {
1409    fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
1410        (&*self).seek(pos)
1411    }
1412    fn stream_len(&mut self) -> io::Result<u64> {
1413        (&*self).stream_len()
1414    }
1415    fn stream_position(&mut self) -> io::Result<u64> {
1416        (&*self).stream_position()
1417    }
1418}
1419
1420#[stable(feature = "io_traits_arc", since = "1.73.0")]
1421impl Read for Arc<File> {
1422    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
1423        (&**self).read(buf)
1424    }
1425    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
1426        (&**self).read_vectored(bufs)
1427    }
1428    fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
1429        (&**self).read_buf(cursor)
1430    }
1431    #[inline]
1432    fn is_read_vectored(&self) -> bool {
1433        (&**self).is_read_vectored()
1434    }
1435    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
1436        (&**self).read_to_end(buf)
1437    }
1438    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
1439        (&**self).read_to_string(buf)
1440    }
1441}
1442#[stable(feature = "io_traits_arc", since = "1.73.0")]
1443impl Write for Arc<File> {
1444    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
1445        (&**self).write(buf)
1446    }
1447    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
1448        (&**self).write_vectored(bufs)
1449    }
1450    #[inline]
1451    fn is_write_vectored(&self) -> bool {
1452        (&**self).is_write_vectored()
1453    }
1454    #[inline]
1455    fn flush(&mut self) -> io::Result<()> {
1456        (&**self).flush()
1457    }
1458}
1459#[stable(feature = "io_traits_arc", since = "1.73.0")]
1460impl Seek for Arc<File> {
1461    fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
1462        (&**self).seek(pos)
1463    }
1464    fn stream_len(&mut self) -> io::Result<u64> {
1465        (&**self).stream_len()
1466    }
1467    fn stream_position(&mut self) -> io::Result<u64> {
1468        (&**self).stream_position()
1469    }
1470}
1471
1472impl OpenOptions {
1473    /// Creates a blank new set of options ready for configuration.
1474    ///
1475    /// All options are initially set to `false`.
1476    ///
1477    /// # Examples
1478    ///
1479    /// ```no_run
1480    /// use std::fs::OpenOptions;
1481    ///
1482    /// let mut options = OpenOptions::new();
1483    /// let file = options.read(true).open("foo.txt");
1484    /// ```
1485    #[cfg_attr(not(test), rustc_diagnostic_item = "open_options_new")]
1486    #[stable(feature = "rust1", since = "1.0.0")]
1487    #[must_use]
1488    pub fn new() -> Self {
1489        OpenOptions(fs_imp::OpenOptions::new())
1490    }
1491
1492    /// Sets the option for read access.
1493    ///
1494    /// This option, when true, will indicate that the file should be
1495    /// `read`-able if opened.
1496    ///
1497    /// # Examples
1498    ///
1499    /// ```no_run
1500    /// use std::fs::OpenOptions;
1501    ///
1502    /// let file = OpenOptions::new().read(true).open("foo.txt");
1503    /// ```
1504    #[stable(feature = "rust1", since = "1.0.0")]
1505    pub fn read(&mut self, read: bool) -> &mut Self {
1506        self.0.read(read);
1507        self
1508    }
1509
1510    /// Sets the option for write access.
1511    ///
1512    /// This option, when true, will indicate that the file should be
1513    /// `write`-able if opened.
1514    ///
1515    /// If the file already exists, any write calls on it will overwrite its
1516    /// contents, without truncating it.
1517    ///
1518    /// # Examples
1519    ///
1520    /// ```no_run
1521    /// use std::fs::OpenOptions;
1522    ///
1523    /// let file = OpenOptions::new().write(true).open("foo.txt");
1524    /// ```
1525    #[stable(feature = "rust1", since = "1.0.0")]
1526    pub fn write(&mut self, write: bool) -> &mut Self {
1527        self.0.write(write);
1528        self
1529    }
1530
1531    /// Sets the option for the append mode.
1532    ///
1533    /// This option, when true, means that writes will append to a file instead
1534    /// of overwriting previous contents.
1535    /// Note that setting `.write(true).append(true)` has the same effect as
1536    /// setting only `.append(true)`.
1537    ///
1538    /// Append mode guarantees that writes will be positioned at the current end of file,
1539    /// even when there are other processes or threads appending to the same file. This is
1540    /// unlike <code>[seek]\([SeekFrom]::[End]\(0))</code> followed by `write()`, which
1541    /// has a race between seeking and writing during which another writer can write, with
1542    /// our `write()` overwriting their data.
1543    ///
1544    /// Keep in mind that this does not necessarily guarantee that data appended by
1545    /// different processes or threads does not interleave. The amount of data accepted a
1546    /// single `write()` call depends on the operating system and file system. A
1547    /// successful `write()` is allowed to write only part of the given data, so even if
1548    /// you're careful to provide the whole message in a single call to `write()`, there
1549    /// is no guarantee that it will be written out in full. If you rely on the filesystem
1550    /// accepting the message in a single write, make sure that all data that belongs
1551    /// together is written in one operation. This can be done by concatenating strings
1552    /// before passing them to [`write()`].
1553    ///
1554    /// If a file is opened with both read and append access, beware that after
1555    /// opening, and after every write, the position for reading may be set at the
1556    /// end of the file. So, before writing, save the current position (using
1557    /// <code>[Seek]::[stream_position]</code>), and restore it before the next read.
1558    ///
1559    /// ## Note
1560    ///
1561    /// This function doesn't create the file if it doesn't exist. Use the
1562    /// [`OpenOptions::create`] method to do so.
1563    ///
1564    /// [`write()`]: Write::write "io::Write::write"
1565    /// [`flush()`]: Write::flush "io::Write::flush"
1566    /// [stream_position]: Seek::stream_position "io::Seek::stream_position"
1567    /// [seek]: Seek::seek "io::Seek::seek"
1568    /// [Current]: SeekFrom::Current "io::SeekFrom::Current"
1569    /// [End]: SeekFrom::End "io::SeekFrom::End"
1570    ///
1571    /// # Examples
1572    ///
1573    /// ```no_run
1574    /// use std::fs::OpenOptions;
1575    ///
1576    /// let file = OpenOptions::new().append(true).open("foo.txt");
1577    /// ```
1578    #[stable(feature = "rust1", since = "1.0.0")]
1579    pub fn append(&mut self, append: bool) -> &mut Self {
1580        self.0.append(append);
1581        self
1582    }
1583
1584    /// Sets the option for truncating a previous file.
1585    ///
1586    /// If a file is successfully opened with this option set to true, it will truncate
1587    /// the file to 0 length if it already exists.
1588    ///
1589    /// The file must be opened with write access for truncate to work.
1590    ///
1591    /// # Examples
1592    ///
1593    /// ```no_run
1594    /// use std::fs::OpenOptions;
1595    ///
1596    /// let file = OpenOptions::new().write(true).truncate(true).open("foo.txt");
1597    /// ```
1598    #[stable(feature = "rust1", since = "1.0.0")]
1599    pub fn truncate(&mut self, truncate: bool) -> &mut Self {
1600        self.0.truncate(truncate);
1601        self
1602    }
1603
1604    /// Sets the option to create a new file, or open it if it already exists.
1605    ///
1606    /// In order for the file to be created, [`OpenOptions::write`] or
1607    /// [`OpenOptions::append`] access must be used.
1608    ///
1609    /// See also [`std::fs::write()`][self::write] for a simple function to
1610    /// create a file with some given data.
1611    ///
1612    /// # Examples
1613    ///
1614    /// ```no_run
1615    /// use std::fs::OpenOptions;
1616    ///
1617    /// let file = OpenOptions::new().write(true).create(true).open("foo.txt");
1618    /// ```
1619    #[stable(feature = "rust1", since = "1.0.0")]
1620    pub fn create(&mut self, create: bool) -> &mut Self {
1621        self.0.create(create);
1622        self
1623    }
1624
1625    /// Sets the option to create a new file, failing if it already exists.
1626    ///
1627    /// No file is allowed to exist at the target location, also no (dangling) symlink. In this
1628    /// way, if the call succeeds, the file returned is guaranteed to be new.
1629    /// If a file exists at the target location, creating a new file will fail with [`AlreadyExists`]
1630    /// or another error based on the situation. See [`OpenOptions::open`] for a
1631    /// non-exhaustive list of likely errors.
1632    ///
1633    /// This option is useful because it is atomic. Otherwise between checking
1634    /// whether a file exists and creating a new one, the file may have been
1635    /// created by another process (a [TOCTOU] race condition / attack).
1636    ///
1637    /// If `.create_new(true)` is set, [`.create()`] and [`.truncate()`] are
1638    /// ignored.
1639    ///
1640    /// The file must be opened with write or append access in order to create
1641    /// a new file.
1642    ///
1643    /// [`.create()`]: OpenOptions::create
1644    /// [`.truncate()`]: OpenOptions::truncate
1645    /// [`AlreadyExists`]: io::ErrorKind::AlreadyExists
1646    /// [TOCTOU]: self#time-of-check-to-time-of-use-toctou
1647    ///
1648    /// # Examples
1649    ///
1650    /// ```no_run
1651    /// use std::fs::OpenOptions;
1652    ///
1653    /// let file = OpenOptions::new().write(true)
1654    ///                              .create_new(true)
1655    ///                              .open("foo.txt");
1656    /// ```
1657    #[stable(feature = "expand_open_options2", since = "1.9.0")]
1658    pub fn create_new(&mut self, create_new: bool) -> &mut Self {
1659        self.0.create_new(create_new);
1660        self
1661    }
1662
1663    /// Opens a file at `path` with the options specified by `self`.
1664    ///
1665    /// # Errors
1666    ///
1667    /// This function will return an error under a number of different
1668    /// circumstances. Some of these error conditions are listed here, together
1669    /// with their [`io::ErrorKind`]. The mapping to [`io::ErrorKind`]s is not
1670    /// part of the compatibility contract of the function.
1671    ///
1672    /// * [`NotFound`]: The specified file does not exist and neither `create`
1673    ///   or `create_new` is set.
1674    /// * [`NotFound`]: One of the directory components of the file path does
1675    ///   not exist.
1676    /// * [`PermissionDenied`]: The user lacks permission to get the specified
1677    ///   access rights for the file.
1678    /// * [`PermissionDenied`]: The user lacks permission to open one of the
1679    ///   directory components of the specified path.
1680    /// * [`AlreadyExists`]: `create_new` was specified and the file already
1681    ///   exists.
1682    /// * [`InvalidInput`]: Invalid combinations of open options (truncate
1683    ///   without write access, no access mode set, etc.).
1684    ///
1685    /// The following errors don't match any existing [`io::ErrorKind`] at the moment:
1686    /// * One of the directory components of the specified file path
1687    ///   was not, in fact, a directory.
1688    /// * Filesystem-level errors: full disk, write permission
1689    ///   requested on a read-only file system, exceeded disk quota, too many
1690    ///   open files, too long filename, too many symbolic links in the
1691    ///   specified path (Unix-like systems only), etc.
1692    ///
1693    /// # Examples
1694    ///
1695    /// ```no_run
1696    /// use std::fs::OpenOptions;
1697    ///
1698    /// let file = OpenOptions::new().read(true).open("foo.txt");
1699    /// ```
1700    ///
1701    /// [`AlreadyExists`]: io::ErrorKind::AlreadyExists
1702    /// [`InvalidInput`]: io::ErrorKind::InvalidInput
1703    /// [`NotFound`]: io::ErrorKind::NotFound
1704    /// [`PermissionDenied`]: io::ErrorKind::PermissionDenied
1705    #[stable(feature = "rust1", since = "1.0.0")]
1706    pub fn open<P: AsRef<Path>>(&self, path: P) -> io::Result<File> {
1707        self._open(path.as_ref())
1708    }
1709
1710    fn _open(&self, path: &Path) -> io::Result<File> {
1711        fs_imp::File::open(path, &self.0).map(|inner| File { inner })
1712    }
1713}
1714
1715impl AsInner<fs_imp::OpenOptions> for OpenOptions {
1716    #[inline]
1717    fn as_inner(&self) -> &fs_imp::OpenOptions {
1718        &self.0
1719    }
1720}
1721
1722impl AsInnerMut<fs_imp::OpenOptions> for OpenOptions {
1723    #[inline]
1724    fn as_inner_mut(&mut self) -> &mut fs_imp::OpenOptions {
1725        &mut self.0
1726    }
1727}
1728
1729impl Metadata {
1730    /// Returns the file type for this metadata.
1731    ///
1732    /// # Examples
1733    ///
1734    /// ```no_run
1735    /// fn main() -> std::io::Result<()> {
1736    ///     use std::fs;
1737    ///
1738    ///     let metadata = fs::metadata("foo.txt")?;
1739    ///
1740    ///     println!("{:?}", metadata.file_type());
1741    ///     Ok(())
1742    /// }
1743    /// ```
1744    #[must_use]
1745    #[stable(feature = "file_type", since = "1.1.0")]
1746    pub fn file_type(&self) -> FileType {
1747        FileType(self.0.file_type())
1748    }
1749
1750    /// Returns `true` if this metadata is for a directory. The
1751    /// result is mutually exclusive to the result of
1752    /// [`Metadata::is_file`], and will be false for symlink metadata
1753    /// obtained from [`symlink_metadata`].
1754    ///
1755    /// # Examples
1756    ///
1757    /// ```no_run
1758    /// fn main() -> std::io::Result<()> {
1759    ///     use std::fs;
1760    ///
1761    ///     let metadata = fs::metadata("foo.txt")?;
1762    ///
1763    ///     assert!(!metadata.is_dir());
1764    ///     Ok(())
1765    /// }
1766    /// ```
1767    #[must_use]
1768    #[stable(feature = "rust1", since = "1.0.0")]
1769    pub fn is_dir(&self) -> bool {
1770        self.file_type().is_dir()
1771    }
1772
1773    /// Returns `true` if this metadata is for a regular file. The
1774    /// result is mutually exclusive to the result of
1775    /// [`Metadata::is_dir`], and will be false for symlink metadata
1776    /// obtained from [`symlink_metadata`].
1777    ///
1778    /// When the goal is simply to read from (or write to) the source, the most
1779    /// reliable way to test the source can be read (or written to) is to open
1780    /// it. Only using `is_file` can break workflows like `diff <( prog_a )` on
1781    /// a Unix-like system for example. See [`File::open`] or
1782    /// [`OpenOptions::open`] for more information.
1783    ///
1784    /// # Examples
1785    ///
1786    /// ```no_run
1787    /// use std::fs;
1788    ///
1789    /// fn main() -> std::io::Result<()> {
1790    ///     let metadata = fs::metadata("foo.txt")?;
1791    ///
1792    ///     assert!(metadata.is_file());
1793    ///     Ok(())
1794    /// }
1795    /// ```
1796    #[must_use]
1797    #[stable(feature = "rust1", since = "1.0.0")]
1798    pub fn is_file(&self) -> bool {
1799        self.file_type().is_file()
1800    }
1801
1802    /// Returns `true` if this metadata is for a symbolic link.
1803    ///
1804    /// # Examples
1805    ///
1806    #[cfg_attr(unix, doc = "```no_run")]
1807    #[cfg_attr(not(unix), doc = "```ignore")]
1808    /// use std::fs;
1809    /// use std::path::Path;
1810    /// use std::os::unix::fs::symlink;
1811    ///
1812    /// fn main() -> std::io::Result<()> {
1813    ///     let link_path = Path::new("link");
1814    ///     symlink("/origin_does_not_exist/", link_path)?;
1815    ///
1816    ///     let metadata = fs::symlink_metadata(link_path)?;
1817    ///
1818    ///     assert!(metadata.is_symlink());
1819    ///     Ok(())
1820    /// }
1821    /// ```
1822    #[must_use]
1823    #[stable(feature = "is_symlink", since = "1.58.0")]
1824    pub fn is_symlink(&self) -> bool {
1825        self.file_type().is_symlink()
1826    }
1827
1828    /// Returns the size of the file, in bytes, this metadata is for.
1829    ///
1830    /// # Examples
1831    ///
1832    /// ```no_run
1833    /// use std::fs;
1834    ///
1835    /// fn main() -> std::io::Result<()> {
1836    ///     let metadata = fs::metadata("foo.txt")?;
1837    ///
1838    ///     assert_eq!(0, metadata.len());
1839    ///     Ok(())
1840    /// }
1841    /// ```
1842    #[must_use]
1843    #[stable(feature = "rust1", since = "1.0.0")]
1844    pub fn len(&self) -> u64 {
1845        self.0.size()
1846    }
1847
1848    /// Returns the permissions of the file this metadata is for.
1849    ///
1850    /// # Examples
1851    ///
1852    /// ```no_run
1853    /// use std::fs;
1854    ///
1855    /// fn main() -> std::io::Result<()> {
1856    ///     let metadata = fs::metadata("foo.txt")?;
1857    ///
1858    ///     assert!(!metadata.permissions().readonly());
1859    ///     Ok(())
1860    /// }
1861    /// ```
1862    #[must_use]
1863    #[stable(feature = "rust1", since = "1.0.0")]
1864    pub fn permissions(&self) -> Permissions {
1865        Permissions(self.0.perm())
1866    }
1867
1868    /// Returns the last modification time listed in this metadata.
1869    ///
1870    /// The returned value corresponds to the `mtime` field of `stat` on Unix
1871    /// platforms and the `ftLastWriteTime` field on Windows platforms.
1872    ///
1873    /// # Errors
1874    ///
1875    /// This field might not be available on all platforms, and will return an
1876    /// `Err` on platforms where it is not available.
1877    ///
1878    /// # Examples
1879    ///
1880    /// ```no_run
1881    /// use std::fs;
1882    ///
1883    /// fn main() -> std::io::Result<()> {
1884    ///     let metadata = fs::metadata("foo.txt")?;
1885    ///
1886    ///     if let Ok(time) = metadata.modified() {
1887    ///         println!("{time:?}");
1888    ///     } else {
1889    ///         println!("Not supported on this platform");
1890    ///     }
1891    ///     Ok(())
1892    /// }
1893    /// ```
1894    #[doc(alias = "mtime", alias = "ftLastWriteTime")]
1895    #[stable(feature = "fs_time", since = "1.10.0")]
1896    pub fn modified(&self) -> io::Result<SystemTime> {
1897        self.0.modified().map(FromInner::from_inner)
1898    }
1899
1900    /// Returns the last access time of this metadata.
1901    ///
1902    /// The returned value corresponds to the `atime` field of `stat` on Unix
1903    /// platforms and the `ftLastAccessTime` field on Windows platforms.
1904    ///
1905    /// Note that not all platforms will keep this field update in a file's
1906    /// metadata, for example Windows has an option to disable updating this
1907    /// time when files are accessed and Linux similarly has `noatime`.
1908    ///
1909    /// # Errors
1910    ///
1911    /// This field might not be available on all platforms, and will return an
1912    /// `Err` on platforms where it is not available.
1913    ///
1914    /// # Examples
1915    ///
1916    /// ```no_run
1917    /// use std::fs;
1918    ///
1919    /// fn main() -> std::io::Result<()> {
1920    ///     let metadata = fs::metadata("foo.txt")?;
1921    ///
1922    ///     if let Ok(time) = metadata.accessed() {
1923    ///         println!("{time:?}");
1924    ///     } else {
1925    ///         println!("Not supported on this platform");
1926    ///     }
1927    ///     Ok(())
1928    /// }
1929    /// ```
1930    #[doc(alias = "atime", alias = "ftLastAccessTime")]
1931    #[stable(feature = "fs_time", since = "1.10.0")]
1932    pub fn accessed(&self) -> io::Result<SystemTime> {
1933        self.0.accessed().map(FromInner::from_inner)
1934    }
1935
1936    /// Returns the creation time listed in this metadata.
1937    ///
1938    /// The returned value corresponds to the `btime` field of `statx` on
1939    /// Linux kernel starting from to 4.11, the `birthtime` field of `stat` on other
1940    /// Unix platforms, and the `ftCreationTime` field on Windows platforms.
1941    ///
1942    /// # Errors
1943    ///
1944    /// This field might not be available on all platforms, and will return an
1945    /// `Err` on platforms or filesystems where it is not available.
1946    ///
1947    /// # Examples
1948    ///
1949    /// ```no_run
1950    /// use std::fs;
1951    ///
1952    /// fn main() -> std::io::Result<()> {
1953    ///     let metadata = fs::metadata("foo.txt")?;
1954    ///
1955    ///     if let Ok(time) = metadata.created() {
1956    ///         println!("{time:?}");
1957    ///     } else {
1958    ///         println!("Not supported on this platform or filesystem");
1959    ///     }
1960    ///     Ok(())
1961    /// }
1962    /// ```
1963    #[doc(alias = "btime", alias = "birthtime", alias = "ftCreationTime")]
1964    #[stable(feature = "fs_time", since = "1.10.0")]
1965    pub fn created(&self) -> io::Result<SystemTime> {
1966        self.0.created().map(FromInner::from_inner)
1967    }
1968}
1969
1970#[stable(feature = "std_debug", since = "1.16.0")]
1971impl fmt::Debug for Metadata {
1972    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1973        let mut debug = f.debug_struct("Metadata");
1974        debug.field("file_type", &self.file_type());
1975        debug.field("permissions", &self.permissions());
1976        debug.field("len", &self.len());
1977        if let Ok(modified) = self.modified() {
1978            debug.field("modified", &modified);
1979        }
1980        if let Ok(accessed) = self.accessed() {
1981            debug.field("accessed", &accessed);
1982        }
1983        if let Ok(created) = self.created() {
1984            debug.field("created", &created);
1985        }
1986        debug.finish_non_exhaustive()
1987    }
1988}
1989
1990impl AsInner<fs_imp::FileAttr> for Metadata {
1991    #[inline]
1992    fn as_inner(&self) -> &fs_imp::FileAttr {
1993        &self.0
1994    }
1995}
1996
1997impl FromInner<fs_imp::FileAttr> for Metadata {
1998    fn from_inner(attr: fs_imp::FileAttr) -> Metadata {
1999        Metadata(attr)
2000    }
2001}
2002
2003impl FileTimes {
2004    /// Creates a new `FileTimes` with no times set.
2005    ///
2006    /// Using the resulting `FileTimes` in [`File::set_times`] will not modify any timestamps.
2007    #[stable(feature = "file_set_times", since = "1.75.0")]
2008    pub fn new() -> Self {
2009        Self::default()
2010    }
2011
2012    /// Set the last access time of a file.
2013    #[stable(feature = "file_set_times", since = "1.75.0")]
2014    pub fn set_accessed(mut self, t: SystemTime) -> Self {
2015        self.0.set_accessed(t.into_inner());
2016        self
2017    }
2018
2019    /// Set the last modified time of a file.
2020    #[stable(feature = "file_set_times", since = "1.75.0")]
2021    pub fn set_modified(mut self, t: SystemTime) -> Self {
2022        self.0.set_modified(t.into_inner());
2023        self
2024    }
2025}
2026
2027impl AsInnerMut<fs_imp::FileTimes> for FileTimes {
2028    fn as_inner_mut(&mut self) -> &mut fs_imp::FileTimes {
2029        &mut self.0
2030    }
2031}
2032
2033// For implementing OS extension traits in `std::os`
2034#[stable(feature = "file_set_times", since = "1.75.0")]
2035impl Sealed for FileTimes {}
2036
2037impl Permissions {
2038    /// Returns `true` if these permissions describe a readonly (unwritable) file.
2039    ///
2040    /// # Note
2041    ///
2042    /// This function does not take Access Control Lists (ACLs), Unix group
2043    /// membership and other nuances into account.
2044    /// Therefore the return value of this function cannot be relied upon
2045    /// to predict whether attempts to read or write the file will actually succeed.
2046    ///
2047    /// # Windows
2048    ///
2049    /// On Windows this returns [`FILE_ATTRIBUTE_READONLY`](https://docs.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants).
2050    /// If `FILE_ATTRIBUTE_READONLY` is set then writes to the file will fail
2051    /// but the user may still have permission to change this flag. If
2052    /// `FILE_ATTRIBUTE_READONLY` is *not* set then writes may still fail due
2053    /// to lack of write permission.
2054    /// The behavior of this attribute for directories depends on the Windows
2055    /// version.
2056    ///
2057    /// # Unix (including macOS)
2058    ///
2059    /// On Unix-based platforms this checks if *any* of the owner, group or others
2060    /// write permission bits are set. It does not consider anything else, including:
2061    ///
2062    /// * Whether the current user is in the file's assigned group.
2063    /// * Permissions granted by ACL.
2064    /// * That `root` user can write to files that do not have any write bits set.
2065    /// * Writable files on a filesystem that is mounted read-only.
2066    ///
2067    /// The [`PermissionsExt`] trait gives direct access to the permission bits but
2068    /// also does not read ACLs.
2069    ///
2070    /// [`PermissionsExt`]: crate::os::unix::fs::PermissionsExt
2071    ///
2072    /// # Examples
2073    ///
2074    /// ```no_run
2075    /// use std::fs::File;
2076    ///
2077    /// fn main() -> std::io::Result<()> {
2078    ///     let mut f = File::create("foo.txt")?;
2079    ///     let metadata = f.metadata()?;
2080    ///
2081    ///     assert_eq!(false, metadata.permissions().readonly());
2082    ///     Ok(())
2083    /// }
2084    /// ```
2085    #[must_use = "call `set_readonly` to modify the readonly flag"]
2086    #[stable(feature = "rust1", since = "1.0.0")]
2087    pub fn readonly(&self) -> bool {
2088        self.0.readonly()
2089    }
2090
2091    /// Modifies the readonly flag for this set of permissions. If the
2092    /// `readonly` argument is `true`, using the resulting `Permission` will
2093    /// update file permissions to forbid writing. Conversely, if it's `false`,
2094    /// using the resulting `Permission` will update file permissions to allow
2095    /// writing.
2096    ///
2097    /// This operation does **not** modify the files attributes. This only
2098    /// changes the in-memory value of these attributes for this `Permissions`
2099    /// instance. To modify the files attributes use the [`set_permissions`]
2100    /// function which commits these attribute changes to the file.
2101    ///
2102    /// # Note
2103    ///
2104    /// `set_readonly(false)` makes the file *world-writable* on Unix.
2105    /// You can use the [`PermissionsExt`] trait on Unix to avoid this issue.
2106    ///
2107    /// It also does not take Access Control Lists (ACLs) or Unix group
2108    /// membership into account.
2109    ///
2110    /// # Windows
2111    ///
2112    /// On Windows this sets or clears [`FILE_ATTRIBUTE_READONLY`](https://docs.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants).
2113    /// If `FILE_ATTRIBUTE_READONLY` is set then writes to the file will fail
2114    /// but the user may still have permission to change this flag. If
2115    /// `FILE_ATTRIBUTE_READONLY` is *not* set then the write may still fail if
2116    /// the user does not have permission to write to the file.
2117    ///
2118    /// In Windows 7 and earlier this attribute prevents deleting empty
2119    /// directories. It does not prevent modifying the directory contents.
2120    /// On later versions of Windows this attribute is ignored for directories.
2121    ///
2122    /// # Unix (including macOS)
2123    ///
2124    /// On Unix-based platforms this sets or clears the write access bit for
2125    /// the owner, group *and* others, equivalent to `chmod a+w <file>`
2126    /// or `chmod a-w <file>` respectively. The latter will grant write access
2127    /// to all users! You can use the [`PermissionsExt`] trait on Unix
2128    /// to avoid this issue.
2129    ///
2130    /// [`PermissionsExt`]: crate::os::unix::fs::PermissionsExt
2131    ///
2132    /// # Examples
2133    ///
2134    /// ```no_run
2135    /// use std::fs::File;
2136    ///
2137    /// fn main() -> std::io::Result<()> {
2138    ///     let f = File::create("foo.txt")?;
2139    ///     let metadata = f.metadata()?;
2140    ///     let mut permissions = metadata.permissions();
2141    ///
2142    ///     permissions.set_readonly(true);
2143    ///
2144    ///     // filesystem doesn't change, only the in memory state of the
2145    ///     // readonly permission
2146    ///     assert_eq!(false, metadata.permissions().readonly());
2147    ///
2148    ///     // just this particular `permissions`.
2149    ///     assert_eq!(true, permissions.readonly());
2150    ///     Ok(())
2151    /// }
2152    /// ```
2153    #[stable(feature = "rust1", since = "1.0.0")]
2154    pub fn set_readonly(&mut self, readonly: bool) {
2155        self.0.set_readonly(readonly)
2156    }
2157}
2158
2159impl FileType {
2160    /// Tests whether this file type represents a directory. The
2161    /// result is mutually exclusive to the results of
2162    /// [`is_file`] and [`is_symlink`]; only zero or one of these
2163    /// tests may pass.
2164    ///
2165    /// [`is_file`]: FileType::is_file
2166    /// [`is_symlink`]: FileType::is_symlink
2167    ///
2168    /// # Examples
2169    ///
2170    /// ```no_run
2171    /// fn main() -> std::io::Result<()> {
2172    ///     use std::fs;
2173    ///
2174    ///     let metadata = fs::metadata("foo.txt")?;
2175    ///     let file_type = metadata.file_type();
2176    ///
2177    ///     assert_eq!(file_type.is_dir(), false);
2178    ///     Ok(())
2179    /// }
2180    /// ```
2181    #[must_use]
2182    #[stable(feature = "file_type", since = "1.1.0")]
2183    pub fn is_dir(&self) -> bool {
2184        self.0.is_dir()
2185    }
2186
2187    /// Tests whether this file type represents a regular file.
2188    /// The result is mutually exclusive to the results of
2189    /// [`is_dir`] and [`is_symlink`]; only zero or one of these
2190    /// tests may pass.
2191    ///
2192    /// When the goal is simply to read from (or write to) the source, the most
2193    /// reliable way to test the source can be read (or written to) is to open
2194    /// it. Only using `is_file` can break workflows like `diff <( prog_a )` on
2195    /// a Unix-like system for example. See [`File::open`] or
2196    /// [`OpenOptions::open`] for more information.
2197    ///
2198    /// [`is_dir`]: FileType::is_dir
2199    /// [`is_symlink`]: FileType::is_symlink
2200    ///
2201    /// # Examples
2202    ///
2203    /// ```no_run
2204    /// fn main() -> std::io::Result<()> {
2205    ///     use std::fs;
2206    ///
2207    ///     let metadata = fs::metadata("foo.txt")?;
2208    ///     let file_type = metadata.file_type();
2209    ///
2210    ///     assert_eq!(file_type.is_file(), true);
2211    ///     Ok(())
2212    /// }
2213    /// ```
2214    #[must_use]
2215    #[stable(feature = "file_type", since = "1.1.0")]
2216    pub fn is_file(&self) -> bool {
2217        self.0.is_file()
2218    }
2219
2220    /// Tests whether this file type represents a symbolic link.
2221    /// The result is mutually exclusive to the results of
2222    /// [`is_dir`] and [`is_file`]; only zero or one of these
2223    /// tests may pass.
2224    ///
2225    /// The underlying [`Metadata`] struct needs to be retrieved
2226    /// with the [`fs::symlink_metadata`] function and not the
2227    /// [`fs::metadata`] function. The [`fs::metadata`] function
2228    /// follows symbolic links, so [`is_symlink`] would always
2229    /// return `false` for the target file.
2230    ///
2231    /// [`fs::metadata`]: metadata
2232    /// [`fs::symlink_metadata`]: symlink_metadata
2233    /// [`is_dir`]: FileType::is_dir
2234    /// [`is_file`]: FileType::is_file
2235    /// [`is_symlink`]: FileType::is_symlink
2236    ///
2237    /// # Examples
2238    ///
2239    /// ```no_run
2240    /// use std::fs;
2241    ///
2242    /// fn main() -> std::io::Result<()> {
2243    ///     let metadata = fs::symlink_metadata("foo.txt")?;
2244    ///     let file_type = metadata.file_type();
2245    ///
2246    ///     assert_eq!(file_type.is_symlink(), false);
2247    ///     Ok(())
2248    /// }
2249    /// ```
2250    #[must_use]
2251    #[stable(feature = "file_type", since = "1.1.0")]
2252    pub fn is_symlink(&self) -> bool {
2253        self.0.is_symlink()
2254    }
2255}
2256
2257#[stable(feature = "std_debug", since = "1.16.0")]
2258impl fmt::Debug for FileType {
2259    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2260        f.debug_struct("FileType")
2261            .field("is_file", &self.is_file())
2262            .field("is_dir", &self.is_dir())
2263            .field("is_symlink", &self.is_symlink())
2264            .finish_non_exhaustive()
2265    }
2266}
2267
2268impl AsInner<fs_imp::FileType> for FileType {
2269    #[inline]
2270    fn as_inner(&self) -> &fs_imp::FileType {
2271        &self.0
2272    }
2273}
2274
2275impl FromInner<fs_imp::FilePermissions> for Permissions {
2276    fn from_inner(f: fs_imp::FilePermissions) -> Permissions {
2277        Permissions(f)
2278    }
2279}
2280
2281impl AsInner<fs_imp::FilePermissions> for Permissions {
2282    #[inline]
2283    fn as_inner(&self) -> &fs_imp::FilePermissions {
2284        &self.0
2285    }
2286}
2287
2288#[stable(feature = "rust1", since = "1.0.0")]
2289impl Iterator for ReadDir {
2290    type Item = io::Result<DirEntry>;
2291
2292    fn next(&mut self) -> Option<io::Result<DirEntry>> {
2293        self.0.next().map(|entry| entry.map(DirEntry))
2294    }
2295}
2296
2297impl DirEntry {
2298    /// Returns the full path to the file that this entry represents.
2299    ///
2300    /// The full path is created by joining the original path to `read_dir`
2301    /// with the filename of this entry.
2302    ///
2303    /// # Examples
2304    ///
2305    /// ```no_run
2306    /// use std::fs;
2307    ///
2308    /// fn main() -> std::io::Result<()> {
2309    ///     for entry in fs::read_dir(".")? {
2310    ///         let dir = entry?;
2311    ///         println!("{:?}", dir.path());
2312    ///     }
2313    ///     Ok(())
2314    /// }
2315    /// ```
2316    ///
2317    /// This prints output like:
2318    ///
2319    /// ```text
2320    /// "./whatever.txt"
2321    /// "./foo.html"
2322    /// "./hello_world.rs"
2323    /// ```
2324    ///
2325    /// The exact text, of course, depends on what files you have in `.`.
2326    #[must_use]
2327    #[stable(feature = "rust1", since = "1.0.0")]
2328    pub fn path(&self) -> PathBuf {
2329        self.0.path()
2330    }
2331
2332    /// Returns the metadata for the file that this entry points at.
2333    ///
2334    /// This function will not traverse symlinks if this entry points at a
2335    /// symlink. To traverse symlinks use [`fs::metadata`] or [`fs::File::metadata`].
2336    ///
2337    /// [`fs::metadata`]: metadata
2338    /// [`fs::File::metadata`]: File::metadata
2339    ///
2340    /// # Platform-specific behavior
2341    ///
2342    /// On Windows this function is cheap to call (no extra system calls
2343    /// needed), but on Unix platforms this function is the equivalent of
2344    /// calling `symlink_metadata` on the path.
2345    ///
2346    /// # Examples
2347    ///
2348    /// ```
2349    /// use std::fs;
2350    ///
2351    /// if let Ok(entries) = fs::read_dir(".") {
2352    ///     for entry in entries {
2353    ///         if let Ok(entry) = entry {
2354    ///             // Here, `entry` is a `DirEntry`.
2355    ///             if let Ok(metadata) = entry.metadata() {
2356    ///                 // Now let's show our entry's permissions!
2357    ///                 println!("{:?}: {:?}", entry.path(), metadata.permissions());
2358    ///             } else {
2359    ///                 println!("Couldn't get metadata for {:?}", entry.path());
2360    ///             }
2361    ///         }
2362    ///     }
2363    /// }
2364    /// ```
2365    #[stable(feature = "dir_entry_ext", since = "1.1.0")]
2366    pub fn metadata(&self) -> io::Result<Metadata> {
2367        self.0.metadata().map(Metadata)
2368    }
2369
2370    /// Returns the file type for the file that this entry points at.
2371    ///
2372    /// This function will not traverse symlinks if this entry points at a
2373    /// symlink.
2374    ///
2375    /// # Platform-specific behavior
2376    ///
2377    /// On Windows and most Unix platforms this function is free (no extra
2378    /// system calls needed), but some Unix platforms may require the equivalent
2379    /// call to `symlink_metadata` to learn about the target file type.
2380    ///
2381    /// # Examples
2382    ///
2383    /// ```
2384    /// use std::fs;
2385    ///
2386    /// if let Ok(entries) = fs::read_dir(".") {
2387    ///     for entry in entries {
2388    ///         if let Ok(entry) = entry {
2389    ///             // Here, `entry` is a `DirEntry`.
2390    ///             if let Ok(file_type) = entry.file_type() {
2391    ///                 // Now let's show our entry's file type!
2392    ///                 println!("{:?}: {:?}", entry.path(), file_type);
2393    ///             } else {
2394    ///                 println!("Couldn't get file type for {:?}", entry.path());
2395    ///             }
2396    ///         }
2397    ///     }
2398    /// }
2399    /// ```
2400    #[stable(feature = "dir_entry_ext", since = "1.1.0")]
2401    pub fn file_type(&self) -> io::Result<FileType> {
2402        self.0.file_type().map(FileType)
2403    }
2404
2405    /// Returns the file name of this directory entry without any
2406    /// leading path component(s).
2407    ///
2408    /// As an example,
2409    /// the output of the function will result in "foo" for all the following paths:
2410    /// - "./foo"
2411    /// - "/the/foo"
2412    /// - "../../foo"
2413    ///
2414    /// # Examples
2415    ///
2416    /// ```
2417    /// use std::fs;
2418    ///
2419    /// if let Ok(entries) = fs::read_dir(".") {
2420    ///     for entry in entries {
2421    ///         if let Ok(entry) = entry {
2422    ///             // Here, `entry` is a `DirEntry`.
2423    ///             println!("{:?}", entry.file_name());
2424    ///         }
2425    ///     }
2426    /// }
2427    /// ```
2428    #[must_use]
2429    #[stable(feature = "dir_entry_ext", since = "1.1.0")]
2430    pub fn file_name(&self) -> OsString {
2431        self.0.file_name()
2432    }
2433}
2434
2435#[stable(feature = "dir_entry_debug", since = "1.13.0")]
2436impl fmt::Debug for DirEntry {
2437    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2438        f.debug_tuple("DirEntry").field(&self.path()).finish()
2439    }
2440}
2441
2442impl AsInner<fs_imp::DirEntry> for DirEntry {
2443    #[inline]
2444    fn as_inner(&self) -> &fs_imp::DirEntry {
2445        &self.0
2446    }
2447}
2448
2449/// Removes a file from the filesystem.
2450///
2451/// Note that there is no
2452/// guarantee that the file is immediately deleted (e.g., depending on
2453/// platform, other open file descriptors may prevent immediate removal).
2454///
2455/// # Platform-specific behavior
2456///
2457/// This function currently corresponds to the `unlink` function on Unix.
2458/// On Windows, `DeleteFile` is used or `CreateFileW` and `SetInformationByHandle` for readonly files.
2459/// Note that, this [may change in the future][changes].
2460///
2461/// [changes]: io#platform-specific-behavior
2462///
2463/// # Errors
2464///
2465/// This function will return an error in the following situations, but is not
2466/// limited to just these cases:
2467///
2468/// * `path` points to a directory.
2469/// * The file doesn't exist.
2470/// * The user lacks permissions to remove the file.
2471///
2472/// This function will only ever return an error of kind `NotFound` if the given
2473/// path does not exist. Note that the inverse is not true,
2474/// ie. if a path does not exist, its removal may fail for a number of reasons,
2475/// such as insufficient permissions.
2476///
2477/// # Examples
2478///
2479/// ```no_run
2480/// use std::fs;
2481///
2482/// fn main() -> std::io::Result<()> {
2483///     fs::remove_file("a.txt")?;
2484///     Ok(())
2485/// }
2486/// ```
2487#[doc(alias = "rm", alias = "unlink", alias = "DeleteFile")]
2488#[stable(feature = "rust1", since = "1.0.0")]
2489pub fn remove_file<P: AsRef<Path>>(path: P) -> io::Result<()> {
2490    fs_imp::remove_file(path.as_ref())
2491}
2492
2493/// Given a path, queries the file system to get information about a file,
2494/// directory, etc.
2495///
2496/// This function will traverse symbolic links to query information about the
2497/// destination file.
2498///
2499/// # Platform-specific behavior
2500///
2501/// This function currently corresponds to the `stat` function on Unix
2502/// and the `GetFileInformationByHandle` function on Windows.
2503/// Note that, this [may change in the future][changes].
2504///
2505/// [changes]: io#platform-specific-behavior
2506///
2507/// # Errors
2508///
2509/// This function will return an error in the following situations, but is not
2510/// limited to just these cases:
2511///
2512/// * The user lacks permissions to perform `metadata` call on `path`.
2513/// * `path` does not exist.
2514///
2515/// # Examples
2516///
2517/// ```rust,no_run
2518/// use std::fs;
2519///
2520/// fn main() -> std::io::Result<()> {
2521///     let attr = fs::metadata("/some/file/path.txt")?;
2522///     // inspect attr ...
2523///     Ok(())
2524/// }
2525/// ```
2526#[doc(alias = "stat")]
2527#[stable(feature = "rust1", since = "1.0.0")]
2528pub fn metadata<P: AsRef<Path>>(path: P) -> io::Result<Metadata> {
2529    fs_imp::metadata(path.as_ref()).map(Metadata)
2530}
2531
2532/// Queries the metadata about a file without following symlinks.
2533///
2534/// # Platform-specific behavior
2535///
2536/// This function currently corresponds to the `lstat` function on Unix
2537/// and the `GetFileInformationByHandle` function on Windows.
2538/// Note that, this [may change in the future][changes].
2539///
2540/// [changes]: io#platform-specific-behavior
2541///
2542/// # Errors
2543///
2544/// This function will return an error in the following situations, but is not
2545/// limited to just these cases:
2546///
2547/// * The user lacks permissions to perform `metadata` call on `path`.
2548/// * `path` does not exist.
2549///
2550/// # Examples
2551///
2552/// ```rust,no_run
2553/// use std::fs;
2554///
2555/// fn main() -> std::io::Result<()> {
2556///     let attr = fs::symlink_metadata("/some/file/path.txt")?;
2557///     // inspect attr ...
2558///     Ok(())
2559/// }
2560/// ```
2561#[doc(alias = "lstat")]
2562#[stable(feature = "symlink_metadata", since = "1.1.0")]
2563pub fn symlink_metadata<P: AsRef<Path>>(path: P) -> io::Result<Metadata> {
2564    fs_imp::symlink_metadata(path.as_ref()).map(Metadata)
2565}
2566
2567/// Renames a file or directory to a new name, replacing the original file if
2568/// `to` already exists.
2569///
2570/// This will not work if the new name is on a different mount point.
2571///
2572/// # Platform-specific behavior
2573///
2574/// This function currently corresponds to the `rename` function on Unix
2575/// and the `MoveFileExW` or `SetFileInformationByHandle` function on Windows.
2576///
2577/// Because of this, the behavior when both `from` and `to` exist differs. On
2578/// Unix, if `from` is a directory, `to` must also be an (empty) directory. If
2579/// `from` is not a directory, `to` must also be not a directory. The behavior
2580/// on Windows is the same on Windows 10 1607 and higher if `FileRenameInfoEx`
2581/// is supported by the filesystem; otherwise, `from` can be anything, but
2582/// `to` must *not* be a directory.
2583///
2584/// Note that, this [may change in the future][changes].
2585///
2586/// [changes]: io#platform-specific-behavior
2587///
2588/// # Errors
2589///
2590/// This function will return an error in the following situations, but is not
2591/// limited to just these cases:
2592///
2593/// * `from` does not exist.
2594/// * The user lacks permissions to view contents.
2595/// * `from` and `to` are on separate filesystems.
2596///
2597/// # Examples
2598///
2599/// ```no_run
2600/// use std::fs;
2601///
2602/// fn main() -> std::io::Result<()> {
2603///     fs::rename("a.txt", "b.txt")?; // Rename a.txt to b.txt
2604///     Ok(())
2605/// }
2606/// ```
2607#[doc(alias = "mv", alias = "MoveFile", alias = "MoveFileEx")]
2608#[stable(feature = "rust1", since = "1.0.0")]
2609pub fn rename<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()> {
2610    fs_imp::rename(from.as_ref(), to.as_ref())
2611}
2612
2613/// Copies the contents of one file to another. This function will also
2614/// copy the permission bits of the original file to the destination file.
2615///
2616/// This function will **overwrite** the contents of `to`.
2617///
2618/// Note that if `from` and `to` both point to the same file, then the file
2619/// will likely get truncated by this operation.
2620///
2621/// On success, the total number of bytes copied is returned and it is equal to
2622/// the length of the `to` file as reported by `metadata`.
2623///
2624/// If you want to copy the contents of one file to another and you’re
2625/// working with [`File`]s, see the [`io::copy`](io::copy()) function.
2626///
2627/// # Platform-specific behavior
2628///
2629/// This function currently corresponds to the `open` function in Unix
2630/// with `O_RDONLY` for `from` and `O_WRONLY`, `O_CREAT`, and `O_TRUNC` for `to`.
2631/// `O_CLOEXEC` is set for returned file descriptors.
2632///
2633/// On Linux (including Android), this function attempts to use `copy_file_range(2)`,
2634/// and falls back to reading and writing if that is not possible.
2635///
2636/// On Windows, this function currently corresponds to `CopyFileEx`. Alternate
2637/// NTFS streams are copied but only the size of the main stream is returned by
2638/// this function.
2639///
2640/// On MacOS, this function corresponds to `fclonefileat` and `fcopyfile`.
2641///
2642/// Note that platform-specific behavior [may change in the future][changes].
2643///
2644/// [changes]: io#platform-specific-behavior
2645///
2646/// # Errors
2647///
2648/// This function will return an error in the following situations, but is not
2649/// limited to just these cases:
2650///
2651/// * `from` is neither a regular file nor a symlink to a regular file.
2652/// * `from` does not exist.
2653/// * The current process does not have the permission rights to read
2654///   `from` or write `to`.
2655/// * The parent directory of `to` doesn't exist.
2656///
2657/// # Examples
2658///
2659/// ```no_run
2660/// use std::fs;
2661///
2662/// fn main() -> std::io::Result<()> {
2663///     fs::copy("foo.txt", "bar.txt")?;  // Copy foo.txt to bar.txt
2664///     Ok(())
2665/// }
2666/// ```
2667#[doc(alias = "cp")]
2668#[doc(alias = "CopyFile", alias = "CopyFileEx")]
2669#[doc(alias = "fclonefileat", alias = "fcopyfile")]
2670#[stable(feature = "rust1", since = "1.0.0")]
2671pub fn copy<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<u64> {
2672    fs_imp::copy(from.as_ref(), to.as_ref())
2673}
2674
2675/// Creates a new hard link on the filesystem.
2676///
2677/// The `link` path will be a link pointing to the `original` path. Note that
2678/// systems often require these two paths to both be located on the same
2679/// filesystem.
2680///
2681/// If `original` names a symbolic link, it is platform-specific whether the
2682/// symbolic link is followed. On platforms where it's possible to not follow
2683/// it, it is not followed, and the created hard link points to the symbolic
2684/// link itself.
2685///
2686/// # Platform-specific behavior
2687///
2688/// This function currently corresponds the `CreateHardLink` function on Windows.
2689/// On most Unix systems, it corresponds to the `linkat` function with no flags.
2690/// On Android, VxWorks, and Redox, it instead corresponds to the `link` function.
2691/// On MacOS, it uses the `linkat` function if it is available, but on very old
2692/// systems where `linkat` is not available, `link` is selected at runtime instead.
2693/// Note that, this [may change in the future][changes].
2694///
2695/// [changes]: io#platform-specific-behavior
2696///
2697/// # Errors
2698///
2699/// This function will return an error in the following situations, but is not
2700/// limited to just these cases:
2701///
2702/// * The `original` path is not a file or doesn't exist.
2703/// * The 'link' path already exists.
2704///
2705/// # Examples
2706///
2707/// ```no_run
2708/// use std::fs;
2709///
2710/// fn main() -> std::io::Result<()> {
2711///     fs::hard_link("a.txt", "b.txt")?; // Hard link a.txt to b.txt
2712///     Ok(())
2713/// }
2714/// ```
2715#[doc(alias = "CreateHardLink", alias = "linkat")]
2716#[stable(feature = "rust1", since = "1.0.0")]
2717pub fn hard_link<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) -> io::Result<()> {
2718    fs_imp::hard_link(original.as_ref(), link.as_ref())
2719}
2720
2721/// Creates a new symbolic link on the filesystem.
2722///
2723/// The `link` path will be a symbolic link pointing to the `original` path.
2724/// On Windows, this will be a file symlink, not a directory symlink;
2725/// for this reason, the platform-specific [`std::os::unix::fs::symlink`]
2726/// and [`std::os::windows::fs::symlink_file`] or [`symlink_dir`] should be
2727/// used instead to make the intent explicit.
2728///
2729/// [`std::os::unix::fs::symlink`]: crate::os::unix::fs::symlink
2730/// [`std::os::windows::fs::symlink_file`]: crate::os::windows::fs::symlink_file
2731/// [`symlink_dir`]: crate::os::windows::fs::symlink_dir
2732///
2733/// # Examples
2734///
2735/// ```no_run
2736/// use std::fs;
2737///
2738/// fn main() -> std::io::Result<()> {
2739///     fs::soft_link("a.txt", "b.txt")?;
2740///     Ok(())
2741/// }
2742/// ```
2743#[stable(feature = "rust1", since = "1.0.0")]
2744#[deprecated(
2745    since = "1.1.0",
2746    note = "replaced with std::os::unix::fs::symlink and \
2747            std::os::windows::fs::{symlink_file, symlink_dir}"
2748)]
2749pub fn soft_link<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) -> io::Result<()> {
2750    fs_imp::symlink(original.as_ref(), link.as_ref())
2751}
2752
2753/// Reads a symbolic link, returning the file that the link points to.
2754///
2755/// # Platform-specific behavior
2756///
2757/// This function currently corresponds to the `readlink` function on Unix
2758/// and the `CreateFile` function with `FILE_FLAG_OPEN_REPARSE_POINT` and
2759/// `FILE_FLAG_BACKUP_SEMANTICS` flags on Windows.
2760/// Note that, this [may change in the future][changes].
2761///
2762/// [changes]: io#platform-specific-behavior
2763///
2764/// # Errors
2765///
2766/// This function will return an error in the following situations, but is not
2767/// limited to just these cases:
2768///
2769/// * `path` is not a symbolic link.
2770/// * `path` does not exist.
2771///
2772/// # Examples
2773///
2774/// ```no_run
2775/// use std::fs;
2776///
2777/// fn main() -> std::io::Result<()> {
2778///     let path = fs::read_link("a.txt")?;
2779///     Ok(())
2780/// }
2781/// ```
2782#[stable(feature = "rust1", since = "1.0.0")]
2783pub fn read_link<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
2784    fs_imp::read_link(path.as_ref())
2785}
2786
2787/// Returns the canonical, absolute form of a path with all intermediate
2788/// components normalized and symbolic links resolved.
2789///
2790/// # Platform-specific behavior
2791///
2792/// This function currently corresponds to the `realpath` function on Unix
2793/// and the `CreateFile` and `GetFinalPathNameByHandle` functions on Windows.
2794/// Note that this [may change in the future][changes].
2795///
2796/// On Windows, this converts the path to use [extended length path][path]
2797/// syntax, which allows your program to use longer path names, but means you
2798/// can only join backslash-delimited paths to it, and it may be incompatible
2799/// with other applications (if passed to the application on the command-line,
2800/// or written to a file another application may read).
2801///
2802/// [changes]: io#platform-specific-behavior
2803/// [path]: https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file
2804///
2805/// # Errors
2806///
2807/// This function will return an error in the following situations, but is not
2808/// limited to just these cases:
2809///
2810/// * `path` does not exist.
2811/// * A non-final component in path is not a directory.
2812///
2813/// # Examples
2814///
2815/// ```no_run
2816/// use std::fs;
2817///
2818/// fn main() -> std::io::Result<()> {
2819///     let path = fs::canonicalize("../a/../foo.txt")?;
2820///     Ok(())
2821/// }
2822/// ```
2823#[doc(alias = "realpath")]
2824#[doc(alias = "GetFinalPathNameByHandle")]
2825#[stable(feature = "fs_canonicalize", since = "1.5.0")]
2826pub fn canonicalize<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
2827    fs_imp::canonicalize(path.as_ref())
2828}
2829
2830/// Creates a new, empty directory at the provided path
2831///
2832/// # Platform-specific behavior
2833///
2834/// This function currently corresponds to the `mkdir` function on Unix
2835/// and the `CreateDirectoryW` function on Windows.
2836/// Note that, this [may change in the future][changes].
2837///
2838/// [changes]: io#platform-specific-behavior
2839///
2840/// **NOTE**: If a parent of the given path doesn't exist, this function will
2841/// return an error. To create a directory and all its missing parents at the
2842/// same time, use the [`create_dir_all`] function.
2843///
2844/// # Errors
2845///
2846/// This function will return an error in the following situations, but is not
2847/// limited to just these cases:
2848///
2849/// * User lacks permissions to create directory at `path`.
2850/// * A parent of the given path doesn't exist. (To create a directory and all
2851///   its missing parents at the same time, use the [`create_dir_all`]
2852///   function.)
2853/// * `path` already exists.
2854///
2855/// # Examples
2856///
2857/// ```no_run
2858/// use std::fs;
2859///
2860/// fn main() -> std::io::Result<()> {
2861///     fs::create_dir("/some/dir")?;
2862///     Ok(())
2863/// }
2864/// ```
2865#[doc(alias = "mkdir", alias = "CreateDirectory")]
2866#[stable(feature = "rust1", since = "1.0.0")]
2867#[cfg_attr(not(test), rustc_diagnostic_item = "fs_create_dir")]
2868pub fn create_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
2869    DirBuilder::new().create(path.as_ref())
2870}
2871
2872/// Recursively create a directory and all of its parent components if they
2873/// are missing.
2874///
2875/// This function is not atomic. If it returns an error, any parent components it was able to create
2876/// will remain.
2877///
2878/// If the empty path is passed to this function, it always succeeds without
2879/// creating any directories.
2880///
2881/// # Platform-specific behavior
2882///
2883/// This function currently corresponds to multiple calls to the `mkdir`
2884/// function on Unix and the `CreateDirectoryW` function on Windows.
2885///
2886/// Note that, this [may change in the future][changes].
2887///
2888/// [changes]: io#platform-specific-behavior
2889///
2890/// # Errors
2891///
2892/// The function will return an error if any directory specified in path does not exist and
2893/// could not be created. There may be other error conditions; see [`fs::create_dir`] for specifics.
2894///
2895/// Notable exception is made for situations where any of the directories
2896/// specified in the `path` could not be created as it was being created concurrently.
2897/// Such cases are considered to be successful. That is, calling `create_dir_all`
2898/// concurrently from multiple threads or processes is guaranteed not to fail
2899/// due to a race condition with itself.
2900///
2901/// [`fs::create_dir`]: create_dir
2902///
2903/// # Examples
2904///
2905/// ```no_run
2906/// use std::fs;
2907///
2908/// fn main() -> std::io::Result<()> {
2909///     fs::create_dir_all("/some/dir")?;
2910///     Ok(())
2911/// }
2912/// ```
2913#[stable(feature = "rust1", since = "1.0.0")]
2914pub fn create_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
2915    DirBuilder::new().recursive(true).create(path.as_ref())
2916}
2917
2918/// Removes an empty directory.
2919///
2920/// If you want to remove a directory that is not empty, as well as all
2921/// of its contents recursively, consider using [`remove_dir_all`]
2922/// instead.
2923///
2924/// # Platform-specific behavior
2925///
2926/// This function currently corresponds to the `rmdir` function on Unix
2927/// and the `RemoveDirectory` function on Windows.
2928/// Note that, this [may change in the future][changes].
2929///
2930/// [changes]: io#platform-specific-behavior
2931///
2932/// # Errors
2933///
2934/// This function will return an error in the following situations, but is not
2935/// limited to just these cases:
2936///
2937/// * `path` doesn't exist.
2938/// * `path` isn't a directory.
2939/// * The user lacks permissions to remove the directory at the provided `path`.
2940/// * The directory isn't empty.
2941///
2942/// This function will only ever return an error of kind `NotFound` if the given
2943/// path does not exist. Note that the inverse is not true,
2944/// ie. if a path does not exist, its removal may fail for a number of reasons,
2945/// such as insufficient permissions.
2946///
2947/// # Examples
2948///
2949/// ```no_run
2950/// use std::fs;
2951///
2952/// fn main() -> std::io::Result<()> {
2953///     fs::remove_dir("/some/dir")?;
2954///     Ok(())
2955/// }
2956/// ```
2957#[doc(alias = "rmdir", alias = "RemoveDirectory")]
2958#[stable(feature = "rust1", since = "1.0.0")]
2959pub fn remove_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
2960    fs_imp::remove_dir(path.as_ref())
2961}
2962
2963/// Removes a directory at this path, after removing all its contents. Use
2964/// carefully!
2965///
2966/// This function does **not** follow symbolic links and it will simply remove the
2967/// symbolic link itself.
2968///
2969/// # Platform-specific behavior
2970///
2971/// These implementation details [may change in the future][changes].
2972///
2973/// - "Unix-like": By default, this function currently corresponds to
2974/// `openat`, `fdopendir`, `unlinkat` and `lstat`
2975/// on Unix-family platforms, except where noted otherwise.
2976/// - "Windows": This function currently corresponds to `CreateFileW`,
2977/// `GetFileInformationByHandleEx`, `SetFileInformationByHandle`, and `NtCreateFile`.
2978///
2979/// ## Time-of-check to time-of-use (TOCTOU) race conditions
2980/// See the [module-level TOCTOU explanation](self#time-of-check-to-time-of-use-toctou).
2981///
2982/// On most platforms, `fs::remove_dir_all` protects against symlink TOCTOU races by default.
2983/// However, on the following platforms, this protection is not provided and the function should
2984/// not be used in security-sensitive contexts:
2985/// - **Miri**: Even when emulating targets where the underlying implementation will protect against
2986///   TOCTOU races, Miri will not do so.
2987/// - **Redox OS**: This function does not protect against TOCTOU races, as Redox does not implement
2988///   the required platform support to do so.
2989///
2990/// [TOCTOU]: self#time-of-check-to-time-of-use-toctou
2991/// [changes]: io#platform-specific-behavior
2992///
2993/// # Errors
2994///
2995/// See [`fs::remove_file`] and [`fs::remove_dir`].
2996///
2997/// [`remove_dir_all`] will fail if [`remove_dir`] or [`remove_file`] fail on *any* constituent
2998/// paths, *including* the root `path`. Consequently,
2999///
3000/// - The directory you are deleting *must* exist, meaning that this function is *not idempotent*.
3001/// - [`remove_dir_all`] will fail if the `path` is *not* a directory.
3002///
3003/// Consider ignoring the error if validating the removal is not required for your use case.
3004///
3005/// This function may return [`io::ErrorKind::DirectoryNotEmpty`] if the directory is concurrently
3006/// written into, which typically indicates some contents were removed but not all.
3007/// [`io::ErrorKind::NotFound`] is only returned if no removal occurs.
3008///
3009/// [`fs::remove_file`]: remove_file
3010/// [`fs::remove_dir`]: remove_dir
3011///
3012/// # Examples
3013///
3014/// ```no_run
3015/// use std::fs;
3016///
3017/// fn main() -> std::io::Result<()> {
3018///     fs::remove_dir_all("/some/dir")?;
3019///     Ok(())
3020/// }
3021/// ```
3022#[stable(feature = "rust1", since = "1.0.0")]
3023pub fn remove_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
3024    fs_imp::remove_dir_all(path.as_ref())
3025}
3026
3027/// Returns an iterator over the entries within a directory.
3028///
3029/// The iterator will yield instances of <code>[io::Result]<[DirEntry]></code>.
3030/// New errors may be encountered after an iterator is initially constructed.
3031/// Entries for the current and parent directories (typically `.` and `..`) are
3032/// skipped.
3033///
3034/// # Platform-specific behavior
3035///
3036/// This function currently corresponds to the `opendir` function on Unix
3037/// and the `FindFirstFileEx` function on Windows. Advancing the iterator
3038/// currently corresponds to `readdir` on Unix and `FindNextFile` on Windows.
3039/// Note that, this [may change in the future][changes].
3040///
3041/// [changes]: io#platform-specific-behavior
3042///
3043/// The order in which this iterator returns entries is platform and filesystem
3044/// dependent.
3045///
3046/// # Errors
3047///
3048/// This function will return an error in the following situations, but is not
3049/// limited to just these cases:
3050///
3051/// * The provided `path` doesn't exist.
3052/// * The process lacks permissions to view the contents.
3053/// * The `path` points at a non-directory file.
3054///
3055/// # Examples
3056///
3057/// ```
3058/// use std::io;
3059/// use std::fs::{self, DirEntry};
3060/// use std::path::Path;
3061///
3062/// // one possible implementation of walking a directory only visiting files
3063/// fn visit_dirs(dir: &Path, cb: &dyn Fn(&DirEntry)) -> io::Result<()> {
3064///     if dir.is_dir() {
3065///         for entry in fs::read_dir(dir)? {
3066///             let entry = entry?;
3067///             let path = entry.path();
3068///             if path.is_dir() {
3069///                 visit_dirs(&path, cb)?;
3070///             } else {
3071///                 cb(&entry);
3072///             }
3073///         }
3074///     }
3075///     Ok(())
3076/// }
3077/// ```
3078///
3079/// ```rust,no_run
3080/// use std::{fs, io};
3081///
3082/// fn main() -> io::Result<()> {
3083///     let mut entries = fs::read_dir(".")?
3084///         .map(|res| res.map(|e| e.path()))
3085///         .collect::<Result<Vec<_>, io::Error>>()?;
3086///
3087///     // The order in which `read_dir` returns entries is not guaranteed. If reproducible
3088///     // ordering is required the entries should be explicitly sorted.
3089///
3090///     entries.sort();
3091///
3092///     // The entries have now been sorted by their path.
3093///
3094///     Ok(())
3095/// }
3096/// ```
3097#[doc(alias = "ls", alias = "opendir", alias = "FindFirstFile", alias = "FindNextFile")]
3098#[stable(feature = "rust1", since = "1.0.0")]
3099pub fn read_dir<P: AsRef<Path>>(path: P) -> io::Result<ReadDir> {
3100    fs_imp::read_dir(path.as_ref()).map(ReadDir)
3101}
3102
3103/// Changes the permissions found on a file or a directory.
3104///
3105/// # Platform-specific behavior
3106///
3107/// This function currently corresponds to the `chmod` function on Unix
3108/// and the `SetFileAttributes` function on Windows.
3109/// Note that, this [may change in the future][changes].
3110///
3111/// [changes]: io#platform-specific-behavior
3112///
3113/// ## Symlinks
3114/// On UNIX-like systems, this function will update the permission bits
3115/// of the file pointed to by the symlink.
3116///
3117/// Note that this behavior can lead to privalage escalation vulnerabilities,
3118/// where the ability to create a symlink in one directory allows you to
3119/// cause the permissions of another file or directory to be modified.
3120///
3121/// For this reason, using this function with symlinks should be avoided.
3122/// When possible, permissions should be set at creation time instead.
3123///
3124/// # Rationale
3125/// POSIX does not specify an `lchmod` function,
3126/// and symlinks can be followed regardless of what permission bits are set.
3127///
3128/// # Errors
3129///
3130/// This function will return an error in the following situations, but is not
3131/// limited to just these cases:
3132///
3133/// * `path` does not exist.
3134/// * The user lacks the permission to change attributes of the file.
3135///
3136/// # Examples
3137///
3138/// ```no_run
3139/// use std::fs;
3140///
3141/// fn main() -> std::io::Result<()> {
3142///     let mut perms = fs::metadata("foo.txt")?.permissions();
3143///     perms.set_readonly(true);
3144///     fs::set_permissions("foo.txt", perms)?;
3145///     Ok(())
3146/// }
3147/// ```
3148#[doc(alias = "chmod", alias = "SetFileAttributes")]
3149#[stable(feature = "set_permissions", since = "1.1.0")]
3150pub fn set_permissions<P: AsRef<Path>>(path: P, perm: Permissions) -> io::Result<()> {
3151    fs_imp::set_permissions(path.as_ref(), perm.0)
3152}
3153
3154impl DirBuilder {
3155    /// Creates a new set of options with default mode/security settings for all
3156    /// platforms and also non-recursive.
3157    ///
3158    /// # Examples
3159    ///
3160    /// ```
3161    /// use std::fs::DirBuilder;
3162    ///
3163    /// let builder = DirBuilder::new();
3164    /// ```
3165    #[stable(feature = "dir_builder", since = "1.6.0")]
3166    #[must_use]
3167    pub fn new() -> DirBuilder {
3168        DirBuilder { inner: fs_imp::DirBuilder::new(), recursive: false }
3169    }
3170
3171    /// Indicates that directories should be created recursively, creating all
3172    /// parent directories. Parents that do not exist are created with the same
3173    /// security and permissions settings.
3174    ///
3175    /// This option defaults to `false`.
3176    ///
3177    /// # Examples
3178    ///
3179    /// ```
3180    /// use std::fs::DirBuilder;
3181    ///
3182    /// let mut builder = DirBuilder::new();
3183    /// builder.recursive(true);
3184    /// ```
3185    #[stable(feature = "dir_builder", since = "1.6.0")]
3186    pub fn recursive(&mut self, recursive: bool) -> &mut Self {
3187        self.recursive = recursive;
3188        self
3189    }
3190
3191    /// Creates the specified directory with the options configured in this
3192    /// builder.
3193    ///
3194    /// It is considered an error if the directory already exists unless
3195    /// recursive mode is enabled.
3196    ///
3197    /// # Examples
3198    ///
3199    /// ```no_run
3200    /// use std::fs::{self, DirBuilder};
3201    ///
3202    /// let path = "/tmp/foo/bar/baz";
3203    /// DirBuilder::new()
3204    ///     .recursive(true)
3205    ///     .create(path).unwrap();
3206    ///
3207    /// assert!(fs::metadata(path).unwrap().is_dir());
3208    /// ```
3209    #[stable(feature = "dir_builder", since = "1.6.0")]
3210    pub fn create<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
3211        self._create(path.as_ref())
3212    }
3213
3214    fn _create(&self, path: &Path) -> io::Result<()> {
3215        if self.recursive { self.create_dir_all(path) } else { self.inner.mkdir(path) }
3216    }
3217
3218    fn create_dir_all(&self, path: &Path) -> io::Result<()> {
3219        if path == Path::new("") {
3220            return Ok(());
3221        }
3222
3223        match self.inner.mkdir(path) {
3224            Ok(()) => return Ok(()),
3225            Err(ref e) if e.kind() == io::ErrorKind::NotFound => {}
3226            Err(_) if path.is_dir() => return Ok(()),
3227            Err(e) => return Err(e),
3228        }
3229        match path.parent() {
3230            Some(p) => self.create_dir_all(p)?,
3231            None => {
3232                return Err(io::const_error!(
3233                    io::ErrorKind::Uncategorized,
3234                    "failed to create whole tree",
3235                ));
3236            }
3237        }
3238        match self.inner.mkdir(path) {
3239            Ok(()) => Ok(()),
3240            Err(_) if path.is_dir() => Ok(()),
3241            Err(e) => Err(e),
3242        }
3243    }
3244}
3245
3246impl AsInnerMut<fs_imp::DirBuilder> for DirBuilder {
3247    #[inline]
3248    fn as_inner_mut(&mut self) -> &mut fs_imp::DirBuilder {
3249        &mut self.inner
3250    }
3251}
3252
3253/// Returns `Ok(true)` if the path points at an existing entity.
3254///
3255/// This function will traverse symbolic links to query information about the
3256/// destination file. In case of broken symbolic links this will return `Ok(false)`.
3257///
3258/// As opposed to the [`Path::exists`] method, this will only return `Ok(true)` or `Ok(false)`
3259/// if the path was _verified_ to exist or not exist. If its existence can neither be confirmed
3260/// nor denied, an `Err(_)` will be propagated instead. This can be the case if e.g. listing
3261/// permission is denied on one of the parent directories.
3262///
3263/// Note that while this avoids some pitfalls of the `exists()` method, it still can not
3264/// prevent time-of-check to time-of-use ([TOCTOU]) bugs. You should only use it in scenarios
3265/// where those bugs are not an issue.
3266///
3267/// # Examples
3268///
3269/// ```no_run
3270/// use std::fs;
3271///
3272/// assert!(!fs::exists("does_not_exist.txt").expect("Can't check existence of file does_not_exist.txt"));
3273/// assert!(fs::exists("/root/secret_file.txt").is_err());
3274/// ```
3275///
3276/// [`Path::exists`]: crate::path::Path::exists
3277/// [TOCTOU]: self#time-of-check-to-time-of-use-toctou
3278#[stable(feature = "fs_try_exists", since = "1.81.0")]
3279#[inline]
3280pub fn exists<P: AsRef<Path>>(path: P) -> io::Result<bool> {
3281    fs_imp::exists(path.as_ref())
3282}
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy