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