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