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