• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Filesystem manipulation operations.
2 //!
3 //! This module contains basic methods to manipulate the contents of the local
4 //! filesystem. All methods in this module represent cross-platform filesystem
5 //! operations. Extra platform-specific functionality can be found in the
6 //! extension traits of `std::os::$platform`.
7 
8 #![stable(feature = "rust1", since = "1.0.0")]
9 #![deny(unsafe_op_in_unsafe_fn)]
10 
11 #[cfg(all(test, not(any(target_os = "emscripten", target_env = "sgx"))))]
12 mod tests;
13 
14 use crate::ffi::OsString;
15 use crate::fmt;
16 use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write};
17 use crate::path::{Path, PathBuf};
18 use crate::sealed::Sealed;
19 use crate::sys::fs as fs_imp;
20 use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
21 use crate::time::SystemTime;
22 
23 /// An object providing access to an open file on the filesystem.
24 ///
25 /// An instance of a `File` can be read and/or written depending on what options
26 /// it was opened with. Files also implement [`Seek`] to alter the logical cursor
27 /// that the file contains internally.
28 ///
29 /// Files are automatically closed when they go out of scope.  Errors detected
30 /// on closing are ignored by the implementation of `Drop`.  Use the method
31 /// [`sync_all`] if these errors must be manually handled.
32 ///
33 /// # Examples
34 ///
35 /// Creates a new file and write bytes to it (you can also use [`write()`]):
36 ///
37 /// ```no_run
38 /// use std::fs::File;
39 /// use std::io::prelude::*;
40 ///
41 /// fn main() -> std::io::Result<()> {
42 ///     let mut file = File::create("foo.txt")?;
43 ///     file.write_all(b"Hello, world!")?;
44 ///     Ok(())
45 /// }
46 /// ```
47 ///
48 /// Read the contents of a file into a [`String`] (you can also use [`read`]):
49 ///
50 /// ```no_run
51 /// use std::fs::File;
52 /// use std::io::prelude::*;
53 ///
54 /// fn main() -> std::io::Result<()> {
55 ///     let mut file = File::open("foo.txt")?;
56 ///     let mut contents = String::new();
57 ///     file.read_to_string(&mut contents)?;
58 ///     assert_eq!(contents, "Hello, world!");
59 ///     Ok(())
60 /// }
61 /// ```
62 ///
63 /// It can be more efficient to read the contents of a file with a buffered
64 /// [`Read`]er. This can be accomplished with [`BufReader<R>`]:
65 ///
66 /// ```no_run
67 /// use std::fs::File;
68 /// use std::io::BufReader;
69 /// use std::io::prelude::*;
70 ///
71 /// fn main() -> std::io::Result<()> {
72 ///     let file = File::open("foo.txt")?;
73 ///     let mut buf_reader = BufReader::new(file);
74 ///     let mut contents = String::new();
75 ///     buf_reader.read_to_string(&mut contents)?;
76 ///     assert_eq!(contents, "Hello, world!");
77 ///     Ok(())
78 /// }
79 /// ```
80 ///
81 /// Note that, although read and write methods require a `&mut File`, because
82 /// of the interfaces for [`Read`] and [`Write`], the holder of a `&File` can
83 /// still modify the file, either through methods that take `&File` or by
84 /// retrieving the underlying OS object and modifying the file that way.
85 /// Additionally, many operating systems allow concurrent modification of files
86 /// by different processes. Avoid assuming that holding a `&File` means that the
87 /// file will not change.
88 ///
89 /// # Platform-specific behavior
90 ///
91 /// On Windows, the implementation of [`Read`] and [`Write`] traits for `File`
92 /// perform synchronous I/O operations. Therefore the underlying file must not
93 /// have been opened for asynchronous I/O (e.g. by using `FILE_FLAG_OVERLAPPED`).
94 ///
95 /// [`BufReader<R>`]: io::BufReader
96 /// [`sync_all`]: File::sync_all
97 #[stable(feature = "rust1", since = "1.0.0")]
98 #[cfg_attr(not(test), rustc_diagnostic_item = "File")]
99 pub struct File {
100     inner: fs_imp::File,
101 }
102 
103 /// Metadata information about a file.
104 ///
105 /// This structure is returned from the [`metadata`] or
106 /// [`symlink_metadata`] function or method and represents known
107 /// metadata about a file such as its permissions, size, modification
108 /// times, etc.
109 #[stable(feature = "rust1", since = "1.0.0")]
110 #[derive(Clone)]
111 pub struct Metadata(fs_imp::FileAttr);
112 
113 /// Iterator over the entries in a directory.
114 ///
115 /// This iterator is returned from the [`read_dir`] function of this module and
116 /// will yield instances of <code>[io::Result]<[DirEntry]></code>. Through a [`DirEntry`]
117 /// information like the entry's path and possibly other metadata can be
118 /// learned.
119 ///
120 /// The order in which this iterator returns entries is platform and filesystem
121 /// dependent.
122 ///
123 /// # Errors
124 ///
125 /// This [`io::Result`] will be an [`Err`] if there's some sort of intermittent
126 /// IO error during iteration.
127 #[stable(feature = "rust1", since = "1.0.0")]
128 #[derive(Debug)]
129 pub struct ReadDir(fs_imp::ReadDir);
130 
131 /// Entries returned by the [`ReadDir`] iterator.
132 ///
133 /// An instance of `DirEntry` represents an entry inside of a directory on the
134 /// filesystem. Each entry can be inspected via methods to learn about the full
135 /// path or possibly other metadata through per-platform extension traits.
136 ///
137 /// # Platform-specific behavior
138 ///
139 /// On Unix, the `DirEntry` struct contains an internal reference to the open
140 /// directory. Holding `DirEntry` objects will consume a file handle even
141 /// after the `ReadDir` iterator is dropped.
142 ///
143 /// Note that this [may change in the future][changes].
144 ///
145 /// [changes]: io#platform-specific-behavior
146 #[stable(feature = "rust1", since = "1.0.0")]
147 pub struct DirEntry(fs_imp::DirEntry);
148 
149 /// Options and flags which can be used to configure how a file is opened.
150 ///
151 /// This builder exposes the ability to configure how a [`File`] is opened and
152 /// what operations are permitted on the open file. The [`File::open`] and
153 /// [`File::create`] methods are aliases for commonly used options using this
154 /// builder.
155 ///
156 /// Generally speaking, when using `OpenOptions`, you'll first call
157 /// [`OpenOptions::new`], then chain calls to methods to set each option, then
158 /// call [`OpenOptions::open`], passing the path of the file you're trying to
159 /// open. This will give you a [`io::Result`] with a [`File`] inside that you
160 /// can further operate on.
161 ///
162 /// # Examples
163 ///
164 /// Opening a file to read:
165 ///
166 /// ```no_run
167 /// use std::fs::OpenOptions;
168 ///
169 /// let file = OpenOptions::new().read(true).open("foo.txt");
170 /// ```
171 ///
172 /// Opening a file for both reading and writing, as well as creating it if it
173 /// doesn't exist:
174 ///
175 /// ```no_run
176 /// use std::fs::OpenOptions;
177 ///
178 /// let file = OpenOptions::new()
179 ///             .read(true)
180 ///             .write(true)
181 ///             .create(true)
182 ///             .open("foo.txt");
183 /// ```
184 #[derive(Clone, Debug)]
185 #[stable(feature = "rust1", since = "1.0.0")]
186 pub struct OpenOptions(fs_imp::OpenOptions);
187 
188 /// Representation of the various timestamps on a file.
189 #[derive(Copy, Clone, Debug, Default)]
190 #[unstable(feature = "file_set_times", issue = "98245")]
191 pub struct FileTimes(fs_imp::FileTimes);
192 
193 /// Representation of the various permissions on a file.
194 ///
195 /// This module only currently provides one bit of information,
196 /// [`Permissions::readonly`], which is exposed on all currently supported
197 /// platforms. Unix-specific functionality, such as mode bits, is available
198 /// through the [`PermissionsExt`] trait.
199 ///
200 /// [`PermissionsExt`]: crate::os::unix::fs::PermissionsExt
201 #[derive(Clone, PartialEq, Eq, Debug)]
202 #[stable(feature = "rust1", since = "1.0.0")]
203 pub struct Permissions(fs_imp::FilePermissions);
204 
205 /// A structure representing a type of file with accessors for each file type.
206 /// It is returned by [`Metadata::file_type`] method.
207 #[stable(feature = "file_type", since = "1.1.0")]
208 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
209 #[cfg_attr(not(test), rustc_diagnostic_item = "FileType")]
210 pub struct FileType(fs_imp::FileType);
211 
212 /// A builder used to create directories in various manners.
213 ///
214 /// This builder also supports platform-specific options.
215 #[stable(feature = "dir_builder", since = "1.6.0")]
216 #[cfg_attr(not(test), rustc_diagnostic_item = "DirBuilder")]
217 #[derive(Debug)]
218 pub struct DirBuilder {
219     inner: fs_imp::DirBuilder,
220     recursive: bool,
221 }
222 
223 /// Read the entire contents of a file into a bytes vector.
224 ///
225 /// This is a convenience function for using [`File::open`] and [`read_to_end`]
226 /// with fewer imports and without an intermediate variable.
227 ///
228 /// [`read_to_end`]: Read::read_to_end
229 ///
230 /// # Errors
231 ///
232 /// This function will return an error if `path` does not already exist.
233 /// Other errors may also be returned according to [`OpenOptions::open`].
234 ///
235 /// It will also return an error if it encounters while reading an error
236 /// of a kind other than [`io::ErrorKind::Interrupted`].
237 ///
238 /// # Examples
239 ///
240 /// ```no_run
241 /// use std::fs;
242 /// use std::net::SocketAddr;
243 ///
244 /// fn main() -> Result<(), Box<dyn std::error::Error + 'static>> {
245 ///     let foo: SocketAddr = String::from_utf8_lossy(&fs::read("address.txt")?).parse()?;
246 ///     Ok(())
247 /// }
248 /// ```
249 #[stable(feature = "fs_read_write_bytes", since = "1.26.0")]
read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>>250 pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
251     fn inner(path: &Path) -> io::Result<Vec<u8>> {
252         let mut file = File::open(path)?;
253         let size = file.metadata().map(|m| m.len() as usize).ok();
254         let mut bytes = Vec::with_capacity(size.unwrap_or(0));
255         io::default_read_to_end(&mut file, &mut bytes, size)?;
256         Ok(bytes)
257     }
258     inner(path.as_ref())
259 }
260 
261 /// Read the entire contents of a file into a string.
262 ///
263 /// This is a convenience function for using [`File::open`] and [`read_to_string`]
264 /// with fewer imports and without an intermediate variable.
265 ///
266 /// [`read_to_string`]: Read::read_to_string
267 ///
268 /// # Errors
269 ///
270 /// This function will return an error if `path` does not already exist.
271 /// Other errors may also be returned according to [`OpenOptions::open`].
272 ///
273 /// It will also return an error if it encounters while reading an error
274 /// of a kind other than [`io::ErrorKind::Interrupted`],
275 /// or if the contents of the file are not valid UTF-8.
276 ///
277 /// # Examples
278 ///
279 /// ```no_run
280 /// use std::fs;
281 /// use std::net::SocketAddr;
282 /// use std::error::Error;
283 ///
284 /// fn main() -> Result<(), Box<dyn Error>> {
285 ///     let foo: SocketAddr = fs::read_to_string("address.txt")?.parse()?;
286 ///     Ok(())
287 /// }
288 /// ```
289 #[stable(feature = "fs_read_write", since = "1.26.0")]
read_to_string<P: AsRef<Path>>(path: P) -> io::Result<String>290 pub fn read_to_string<P: AsRef<Path>>(path: P) -> io::Result<String> {
291     fn inner(path: &Path) -> io::Result<String> {
292         let mut file = File::open(path)?;
293         let size = file.metadata().map(|m| m.len() as usize).ok();
294         let mut string = String::with_capacity(size.unwrap_or(0));
295         io::default_read_to_string(&mut file, &mut string, size)?;
296         Ok(string)
297     }
298     inner(path.as_ref())
299 }
300 
301 /// Write a slice as the entire contents of a file.
302 ///
303 /// This function will create a file if it does not exist,
304 /// and will entirely replace its contents if it does.
305 ///
306 /// Depending on the platform, this function may fail if the
307 /// full directory path does not exist.
308 ///
309 /// This is a convenience function for using [`File::create`] and [`write_all`]
310 /// with fewer imports.
311 ///
312 /// [`write_all`]: Write::write_all
313 ///
314 /// # Examples
315 ///
316 /// ```no_run
317 /// use std::fs;
318 ///
319 /// fn main() -> std::io::Result<()> {
320 ///     fs::write("foo.txt", b"Lorem ipsum")?;
321 ///     fs::write("bar.txt", "dolor sit")?;
322 ///     Ok(())
323 /// }
324 /// ```
325 #[stable(feature = "fs_read_write_bytes", since = "1.26.0")]
write<P: AsRef<Path>, C: AsRef<[u8]>>(path: P, contents: C) -> io::Result<()>326 pub fn write<P: AsRef<Path>, C: AsRef<[u8]>>(path: P, contents: C) -> io::Result<()> {
327     fn inner(path: &Path, contents: &[u8]) -> io::Result<()> {
328         File::create(path)?.write_all(contents)
329     }
330     inner(path.as_ref(), contents.as_ref())
331 }
332 
333 impl File {
334     /// Attempts to open a file in read-only mode.
335     ///
336     /// See the [`OpenOptions::open`] method for more details.
337     ///
338     /// If you only need to read the entire file contents,
339     /// consider [`std::fs::read()`][self::read] or
340     /// [`std::fs::read_to_string()`][self::read_to_string] instead.
341     ///
342     /// # Errors
343     ///
344     /// This function will return an error if `path` does not already exist.
345     /// Other errors may also be returned according to [`OpenOptions::open`].
346     ///
347     /// # Examples
348     ///
349     /// ```no_run
350     /// use std::fs::File;
351     /// use std::io::Read;
352     ///
353     /// fn main() -> std::io::Result<()> {
354     ///     let mut f = File::open("foo.txt")?;
355     ///     let mut data = vec![];
356     ///     f.read_to_end(&mut data)?;
357     ///     Ok(())
358     /// }
359     /// ```
360     #[stable(feature = "rust1", since = "1.0.0")]
open<P: AsRef<Path>>(path: P) -> io::Result<File>361     pub fn open<P: AsRef<Path>>(path: P) -> io::Result<File> {
362         OpenOptions::new().read(true).open(path.as_ref())
363     }
364 
365     /// Opens a file in write-only mode.
366     ///
367     /// This function will create a file if it does not exist,
368     /// and will truncate it if it does.
369     ///
370     /// Depending on the platform, this function may fail if the
371     /// full directory path does not exist.
372     /// See the [`OpenOptions::open`] function for more details.
373     ///
374     /// See also [`std::fs::write()`][self::write] for a simple function to
375     /// create a file with a given data.
376     ///
377     /// # Examples
378     ///
379     /// ```no_run
380     /// use std::fs::File;
381     /// use std::io::Write;
382     ///
383     /// fn main() -> std::io::Result<()> {
384     ///     let mut f = File::create("foo.txt")?;
385     ///     f.write_all(&1234_u32.to_be_bytes())?;
386     ///     Ok(())
387     /// }
388     /// ```
389     #[stable(feature = "rust1", since = "1.0.0")]
create<P: AsRef<Path>>(path: P) -> io::Result<File>390     pub fn create<P: AsRef<Path>>(path: P) -> io::Result<File> {
391         OpenOptions::new().write(true).create(true).truncate(true).open(path.as_ref())
392     }
393 
394     /// Creates a new file in read-write mode; error if the file exists.
395     ///
396     /// This function will create a file if it does not exist, or return an error if it does. This
397     /// way, if the call succeeds, the file returned is guaranteed to be new.
398     ///
399     /// This option is useful because it is atomic. Otherwise between checking whether a file
400     /// exists and creating a new one, the file may have been created by another process (a TOCTOU
401     /// race condition / attack).
402     ///
403     /// This can also be written using
404     /// `File::options().read(true).write(true).create_new(true).open(...)`.
405     ///
406     /// # Examples
407     ///
408     /// ```no_run
409     /// #![feature(file_create_new)]
410     ///
411     /// use std::fs::File;
412     /// use std::io::Write;
413     ///
414     /// fn main() -> std::io::Result<()> {
415     ///     let mut f = File::create_new("foo.txt")?;
416     ///     f.write_all("Hello, world!".as_bytes())?;
417     ///     Ok(())
418     /// }
419     /// ```
420     #[unstable(feature = "file_create_new", issue = "105135")]
create_new<P: AsRef<Path>>(path: P) -> io::Result<File>421     pub fn create_new<P: AsRef<Path>>(path: P) -> io::Result<File> {
422         OpenOptions::new().read(true).write(true).create_new(true).open(path.as_ref())
423     }
424 
425     /// Returns a new OpenOptions object.
426     ///
427     /// This function returns a new OpenOptions object that you can use to
428     /// open or create a file with specific options if `open()` or `create()`
429     /// are not appropriate.
430     ///
431     /// It is equivalent to `OpenOptions::new()`, but allows you to write more
432     /// readable code. Instead of
433     /// `OpenOptions::new().append(true).open("example.log")`,
434     /// you can write `File::options().append(true).open("example.log")`. This
435     /// also avoids the need to import `OpenOptions`.
436     ///
437     /// See the [`OpenOptions::new`] function for more details.
438     ///
439     /// # Examples
440     ///
441     /// ```no_run
442     /// use std::fs::File;
443     /// use std::io::Write;
444     ///
445     /// fn main() -> std::io::Result<()> {
446     ///     let mut f = File::options().append(true).open("example.log")?;
447     ///     writeln!(&mut f, "new line")?;
448     ///     Ok(())
449     /// }
450     /// ```
451     #[must_use]
452     #[stable(feature = "with_options", since = "1.58.0")]
options() -> OpenOptions453     pub fn options() -> OpenOptions {
454         OpenOptions::new()
455     }
456 
457     /// Attempts to sync all OS-internal metadata to disk.
458     ///
459     /// This function will attempt to ensure that all in-memory data reaches the
460     /// filesystem before returning.
461     ///
462     /// This can be used to handle errors that would otherwise only be caught
463     /// when the `File` is closed.  Dropping a file will ignore errors in
464     /// synchronizing this in-memory data.
465     ///
466     /// # Examples
467     ///
468     /// ```no_run
469     /// use std::fs::File;
470     /// use std::io::prelude::*;
471     ///
472     /// fn main() -> std::io::Result<()> {
473     ///     let mut f = File::create("foo.txt")?;
474     ///     f.write_all(b"Hello, world!")?;
475     ///
476     ///     f.sync_all()?;
477     ///     Ok(())
478     /// }
479     /// ```
480     #[stable(feature = "rust1", since = "1.0.0")]
sync_all(&self) -> io::Result<()>481     pub fn sync_all(&self) -> io::Result<()> {
482         self.inner.fsync()
483     }
484 
485     /// This function is similar to [`sync_all`], except that it might not
486     /// synchronize file metadata to the filesystem.
487     ///
488     /// This is intended for use cases that must synchronize content, but don't
489     /// need the metadata on disk. The goal of this method is to reduce disk
490     /// operations.
491     ///
492     /// Note that some platforms may simply implement this in terms of
493     /// [`sync_all`].
494     ///
495     /// [`sync_all`]: File::sync_all
496     ///
497     /// # Examples
498     ///
499     /// ```no_run
500     /// use std::fs::File;
501     /// use std::io::prelude::*;
502     ///
503     /// fn main() -> std::io::Result<()> {
504     ///     let mut f = File::create("foo.txt")?;
505     ///     f.write_all(b"Hello, world!")?;
506     ///
507     ///     f.sync_data()?;
508     ///     Ok(())
509     /// }
510     /// ```
511     #[stable(feature = "rust1", since = "1.0.0")]
sync_data(&self) -> io::Result<()>512     pub fn sync_data(&self) -> io::Result<()> {
513         self.inner.datasync()
514     }
515 
516     /// Truncates or extends the underlying file, updating the size of
517     /// this file to become `size`.
518     ///
519     /// If the `size` is less than the current file's size, then the file will
520     /// be shrunk. If it is greater than the current file's size, then the file
521     /// will be extended to `size` and have all of the intermediate data filled
522     /// in with 0s.
523     ///
524     /// The file's cursor isn't changed. In particular, if the cursor was at the
525     /// end and the file is shrunk using this operation, the cursor will now be
526     /// past the end.
527     ///
528     /// # Errors
529     ///
530     /// This function will return an error if the file is not opened for writing.
531     /// Also, [`std::io::ErrorKind::InvalidInput`](crate::io::ErrorKind::InvalidInput)
532     /// will be returned if the desired length would cause an overflow due to
533     /// the implementation specifics.
534     ///
535     /// # Examples
536     ///
537     /// ```no_run
538     /// use std::fs::File;
539     ///
540     /// fn main() -> std::io::Result<()> {
541     ///     let mut f = File::create("foo.txt")?;
542     ///     f.set_len(10)?;
543     ///     Ok(())
544     /// }
545     /// ```
546     ///
547     /// Note that this method alters the content of the underlying file, even
548     /// though it takes `&self` rather than `&mut self`.
549     #[stable(feature = "rust1", since = "1.0.0")]
set_len(&self, size: u64) -> io::Result<()>550     pub fn set_len(&self, size: u64) -> io::Result<()> {
551         self.inner.truncate(size)
552     }
553 
554     /// Queries metadata about the underlying file.
555     ///
556     /// # Examples
557     ///
558     /// ```no_run
559     /// use std::fs::File;
560     ///
561     /// fn main() -> std::io::Result<()> {
562     ///     let mut f = File::open("foo.txt")?;
563     ///     let metadata = f.metadata()?;
564     ///     Ok(())
565     /// }
566     /// ```
567     #[stable(feature = "rust1", since = "1.0.0")]
metadata(&self) -> io::Result<Metadata>568     pub fn metadata(&self) -> io::Result<Metadata> {
569         self.inner.file_attr().map(Metadata)
570     }
571 
572     /// Creates a new `File` instance that shares the same underlying file handle
573     /// as the existing `File` instance. Reads, writes, and seeks will affect
574     /// both `File` instances simultaneously.
575     ///
576     /// # Examples
577     ///
578     /// Creates two handles for a file named `foo.txt`:
579     ///
580     /// ```no_run
581     /// use std::fs::File;
582     ///
583     /// fn main() -> std::io::Result<()> {
584     ///     let mut file = File::open("foo.txt")?;
585     ///     let file_copy = file.try_clone()?;
586     ///     Ok(())
587     /// }
588     /// ```
589     ///
590     /// Assuming there’s a file named `foo.txt` with contents `abcdef\n`, create
591     /// two handles, seek one of them, and read the remaining bytes from the
592     /// other handle:
593     ///
594     /// ```no_run
595     /// use std::fs::File;
596     /// use std::io::SeekFrom;
597     /// use std::io::prelude::*;
598     ///
599     /// fn main() -> std::io::Result<()> {
600     ///     let mut file = File::open("foo.txt")?;
601     ///     let mut file_copy = file.try_clone()?;
602     ///
603     ///     file.seek(SeekFrom::Start(3))?;
604     ///
605     ///     let mut contents = vec![];
606     ///     file_copy.read_to_end(&mut contents)?;
607     ///     assert_eq!(contents, b"def\n");
608     ///     Ok(())
609     /// }
610     /// ```
611     #[stable(feature = "file_try_clone", since = "1.9.0")]
try_clone(&self) -> io::Result<File>612     pub fn try_clone(&self) -> io::Result<File> {
613         Ok(File { inner: self.inner.duplicate()? })
614     }
615 
616     /// Changes the permissions on the underlying file.
617     ///
618     /// # Platform-specific behavior
619     ///
620     /// This function currently corresponds to the `fchmod` function on Unix and
621     /// the `SetFileInformationByHandle` function on Windows. Note that, this
622     /// [may change in the future][changes].
623     ///
624     /// [changes]: io#platform-specific-behavior
625     ///
626     /// # Errors
627     ///
628     /// This function will return an error if the user lacks permission change
629     /// attributes on the underlying file. It may also return an error in other
630     /// os-specific unspecified cases.
631     ///
632     /// # Examples
633     ///
634     /// ```no_run
635     /// fn main() -> std::io::Result<()> {
636     ///     use std::fs::File;
637     ///
638     ///     let file = File::open("foo.txt")?;
639     ///     let mut perms = file.metadata()?.permissions();
640     ///     perms.set_readonly(true);
641     ///     file.set_permissions(perms)?;
642     ///     Ok(())
643     /// }
644     /// ```
645     ///
646     /// Note that this method alters the permissions of the underlying file,
647     /// even though it takes `&self` rather than `&mut self`.
648     #[stable(feature = "set_permissions_atomic", since = "1.16.0")]
set_permissions(&self, perm: Permissions) -> io::Result<()>649     pub fn set_permissions(&self, perm: Permissions) -> io::Result<()> {
650         self.inner.set_permissions(perm.0)
651     }
652 
653     /// Changes the timestamps of the underlying file.
654     ///
655     /// # Platform-specific behavior
656     ///
657     /// This function currently corresponds to the `futimens` function on Unix (falling back to
658     /// `futimes` on macOS before 10.13) and the `SetFileTime` function on Windows. Note that this
659     /// [may change in the future][changes].
660     ///
661     /// [changes]: io#platform-specific-behavior
662     ///
663     /// # Errors
664     ///
665     /// This function will return an error if the user lacks permission to change timestamps on the
666     /// underlying file. It may also return an error in other os-specific unspecified cases.
667     ///
668     /// This function may return an error if the operating system lacks support to change one or
669     /// more of the timestamps set in the `FileTimes` structure.
670     ///
671     /// # Examples
672     ///
673     /// ```no_run
674     /// #![feature(file_set_times)]
675     ///
676     /// fn main() -> std::io::Result<()> {
677     ///     use std::fs::{self, File, FileTimes};
678     ///
679     ///     let src = fs::metadata("src")?;
680     ///     let dest = File::options().write(true).open("dest")?;
681     ///     let times = FileTimes::new()
682     ///         .set_accessed(src.accessed()?)
683     ///         .set_modified(src.modified()?);
684     ///     dest.set_times(times)?;
685     ///     Ok(())
686     /// }
687     /// ```
688     #[unstable(feature = "file_set_times", issue = "98245")]
689     #[doc(alias = "futimens")]
690     #[doc(alias = "futimes")]
691     #[doc(alias = "SetFileTime")]
set_times(&self, times: FileTimes) -> io::Result<()>692     pub fn set_times(&self, times: FileTimes) -> io::Result<()> {
693         self.inner.set_times(times.0)
694     }
695 
696     /// Changes the modification time of the underlying file.
697     ///
698     /// This is an alias for `set_times(FileTimes::new().set_modified(time))`.
699     #[unstable(feature = "file_set_times", issue = "98245")]
700     #[inline]
set_modified(&self, time: SystemTime) -> io::Result<()>701     pub fn set_modified(&self, time: SystemTime) -> io::Result<()> {
702         self.set_times(FileTimes::new().set_modified(time))
703     }
704 }
705 
706 // In addition to the `impl`s here, `File` also has `impl`s for
707 // `AsFd`/`From<OwnedFd>`/`Into<OwnedFd>` and
708 // `AsRawFd`/`IntoRawFd`/`FromRawFd`, on Unix and WASI, and
709 // `AsHandle`/`From<OwnedHandle>`/`Into<OwnedHandle>` and
710 // `AsRawHandle`/`IntoRawHandle`/`FromRawHandle` on Windows.
711 
712 impl AsInner<fs_imp::File> for File {
713     #[inline]
as_inner(&self) -> &fs_imp::File714     fn as_inner(&self) -> &fs_imp::File {
715         &self.inner
716     }
717 }
718 impl FromInner<fs_imp::File> for File {
from_inner(f: fs_imp::File) -> File719     fn from_inner(f: fs_imp::File) -> File {
720         File { inner: f }
721     }
722 }
723 impl IntoInner<fs_imp::File> for File {
into_inner(self) -> fs_imp::File724     fn into_inner(self) -> fs_imp::File {
725         self.inner
726     }
727 }
728 
729 #[stable(feature = "rust1", since = "1.0.0")]
730 impl fmt::Debug for File {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result731     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
732         self.inner.fmt(f)
733     }
734 }
735 
736 /// Indicates how much extra capacity is needed to read the rest of the file.
buffer_capacity_required(mut file: &File) -> Option<usize>737 fn buffer_capacity_required(mut file: &File) -> Option<usize> {
738     let size = file.metadata().map(|m| m.len()).ok()?;
739     let pos = file.stream_position().ok()?;
740     // Don't worry about `usize` overflow because reading will fail regardless
741     // in that case.
742     Some(size.saturating_sub(pos) as usize)
743 }
744 
745 #[stable(feature = "rust1", since = "1.0.0")]
746 impl Read for File {
read(&mut self, buf: &mut [u8]) -> io::Result<usize>747     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
748         self.inner.read(buf)
749     }
750 
read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize>751     fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
752         self.inner.read_vectored(bufs)
753     }
754 
read_buf(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()>755     fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
756         self.inner.read_buf(cursor)
757     }
758 
759     #[inline]
is_read_vectored(&self) -> bool760     fn is_read_vectored(&self) -> bool {
761         self.inner.is_read_vectored()
762     }
763 
764     // Reserves space in the buffer based on the file size when available.
read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize>765     fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
766         let size = buffer_capacity_required(self);
767         buf.reserve(size.unwrap_or(0));
768         io::default_read_to_end(self, buf, size)
769     }
770 
771     // Reserves space in the buffer based on the file size when available.
read_to_string(&mut self, buf: &mut String) -> io::Result<usize>772     fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
773         let size = buffer_capacity_required(self);
774         buf.reserve(size.unwrap_or(0));
775         io::default_read_to_string(self, buf, size)
776     }
777 }
778 #[stable(feature = "rust1", since = "1.0.0")]
779 impl Write for File {
write(&mut self, buf: &[u8]) -> io::Result<usize>780     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
781         self.inner.write(buf)
782     }
783 
write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize>784     fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
785         self.inner.write_vectored(bufs)
786     }
787 
788     #[inline]
is_write_vectored(&self) -> bool789     fn is_write_vectored(&self) -> bool {
790         self.inner.is_write_vectored()
791     }
792 
flush(&mut self) -> io::Result<()>793     fn flush(&mut self) -> io::Result<()> {
794         self.inner.flush()
795     }
796 }
797 #[stable(feature = "rust1", since = "1.0.0")]
798 impl Seek for File {
seek(&mut self, pos: SeekFrom) -> io::Result<u64>799     fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
800         self.inner.seek(pos)
801     }
802 }
803 #[stable(feature = "rust1", since = "1.0.0")]
804 impl Read for &File {
read(&mut self, buf: &mut [u8]) -> io::Result<usize>805     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
806         self.inner.read(buf)
807     }
808 
read_buf(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()>809     fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
810         self.inner.read_buf(cursor)
811     }
812 
read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize>813     fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
814         self.inner.read_vectored(bufs)
815     }
816 
817     #[inline]
is_read_vectored(&self) -> bool818     fn is_read_vectored(&self) -> bool {
819         self.inner.is_read_vectored()
820     }
821 
822     // Reserves space in the buffer based on the file size when available.
read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize>823     fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
824         let size = buffer_capacity_required(self);
825         buf.reserve(size.unwrap_or(0));
826         io::default_read_to_end(self, buf, size)
827     }
828 
829     // Reserves space in the buffer based on the file size when available.
read_to_string(&mut self, buf: &mut String) -> io::Result<usize>830     fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
831         let size = buffer_capacity_required(self);
832         buf.reserve(size.unwrap_or(0));
833         io::default_read_to_string(self, buf, size)
834     }
835 }
836 #[stable(feature = "rust1", since = "1.0.0")]
837 impl Write for &File {
write(&mut self, buf: &[u8]) -> io::Result<usize>838     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
839         self.inner.write(buf)
840     }
841 
write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize>842     fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
843         self.inner.write_vectored(bufs)
844     }
845 
846     #[inline]
is_write_vectored(&self) -> bool847     fn is_write_vectored(&self) -> bool {
848         self.inner.is_write_vectored()
849     }
850 
flush(&mut self) -> io::Result<()>851     fn flush(&mut self) -> io::Result<()> {
852         self.inner.flush()
853     }
854 }
855 #[stable(feature = "rust1", since = "1.0.0")]
856 impl Seek for &File {
seek(&mut self, pos: SeekFrom) -> io::Result<u64>857     fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
858         self.inner.seek(pos)
859     }
860 }
861 
862 impl OpenOptions {
863     /// Creates a blank new set of options ready for configuration.
864     ///
865     /// All options are initially set to `false`.
866     ///
867     /// # Examples
868     ///
869     /// ```no_run
870     /// use std::fs::OpenOptions;
871     ///
872     /// let mut options = OpenOptions::new();
873     /// let file = options.read(true).open("foo.txt");
874     /// ```
875     #[stable(feature = "rust1", since = "1.0.0")]
876     #[must_use]
new() -> Self877     pub fn new() -> Self {
878         OpenOptions(fs_imp::OpenOptions::new())
879     }
880 
881     /// Sets the option for read access.
882     ///
883     /// This option, when true, will indicate that the file should be
884     /// `read`-able if opened.
885     ///
886     /// # Examples
887     ///
888     /// ```no_run
889     /// use std::fs::OpenOptions;
890     ///
891     /// let file = OpenOptions::new().read(true).open("foo.txt");
892     /// ```
893     #[stable(feature = "rust1", since = "1.0.0")]
read(&mut self, read: bool) -> &mut Self894     pub fn read(&mut self, read: bool) -> &mut Self {
895         self.0.read(read);
896         self
897     }
898 
899     /// Sets the option for write access.
900     ///
901     /// This option, when true, will indicate that the file should be
902     /// `write`-able if opened.
903     ///
904     /// If the file already exists, any write calls on it will overwrite its
905     /// contents, without truncating it.
906     ///
907     /// # Examples
908     ///
909     /// ```no_run
910     /// use std::fs::OpenOptions;
911     ///
912     /// let file = OpenOptions::new().write(true).open("foo.txt");
913     /// ```
914     #[stable(feature = "rust1", since = "1.0.0")]
write(&mut self, write: bool) -> &mut Self915     pub fn write(&mut self, write: bool) -> &mut Self {
916         self.0.write(write);
917         self
918     }
919 
920     /// Sets the option for the append mode.
921     ///
922     /// This option, when true, means that writes will append to a file instead
923     /// of overwriting previous contents.
924     /// Note that setting `.write(true).append(true)` has the same effect as
925     /// setting only `.append(true)`.
926     ///
927     /// For most filesystems, the operating system guarantees that all writes are
928     /// atomic: no writes get mangled because another process writes at the same
929     /// time.
930     ///
931     /// One maybe obvious note when using append-mode: make sure that all data
932     /// that belongs together is written to the file in one operation. This
933     /// can be done by concatenating strings before passing them to [`write()`],
934     /// or using a buffered writer (with a buffer of adequate size),
935     /// and calling [`flush()`] when the message is complete.
936     ///
937     /// If a file is opened with both read and append access, beware that after
938     /// opening, and after every write, the position for reading may be set at the
939     /// end of the file. So, before writing, save the current position (using
940     /// <code>[seek]\([SeekFrom]::[Current]\(0))</code>), and restore it before the next read.
941     ///
942     /// ## Note
943     ///
944     /// This function doesn't create the file if it doesn't exist. Use the
945     /// [`OpenOptions::create`] method to do so.
946     ///
947     /// [`write()`]: Write::write "io::Write::write"
948     /// [`flush()`]: Write::flush "io::Write::flush"
949     /// [seek]: Seek::seek "io::Seek::seek"
950     /// [Current]: SeekFrom::Current "io::SeekFrom::Current"
951     ///
952     /// # Examples
953     ///
954     /// ```no_run
955     /// use std::fs::OpenOptions;
956     ///
957     /// let file = OpenOptions::new().append(true).open("foo.txt");
958     /// ```
959     #[stable(feature = "rust1", since = "1.0.0")]
append(&mut self, append: bool) -> &mut Self960     pub fn append(&mut self, append: bool) -> &mut Self {
961         self.0.append(append);
962         self
963     }
964 
965     /// Sets the option for truncating a previous file.
966     ///
967     /// If a file is successfully opened with this option set it will truncate
968     /// the file to 0 length if it already exists.
969     ///
970     /// The file must be opened with write access for truncate to work.
971     ///
972     /// # Examples
973     ///
974     /// ```no_run
975     /// use std::fs::OpenOptions;
976     ///
977     /// let file = OpenOptions::new().write(true).truncate(true).open("foo.txt");
978     /// ```
979     #[stable(feature = "rust1", since = "1.0.0")]
truncate(&mut self, truncate: bool) -> &mut Self980     pub fn truncate(&mut self, truncate: bool) -> &mut Self {
981         self.0.truncate(truncate);
982         self
983     }
984 
985     /// Sets the option to create a new file, or open it if it already exists.
986     ///
987     /// In order for the file to be created, [`OpenOptions::write`] or
988     /// [`OpenOptions::append`] access must be used.
989     ///
990     /// See also [`std::fs::write()`][self::write] for a simple function to
991     /// create a file with a given data.
992     ///
993     /// # Examples
994     ///
995     /// ```no_run
996     /// use std::fs::OpenOptions;
997     ///
998     /// let file = OpenOptions::new().write(true).create(true).open("foo.txt");
999     /// ```
1000     #[stable(feature = "rust1", since = "1.0.0")]
create(&mut self, create: bool) -> &mut Self1001     pub fn create(&mut self, create: bool) -> &mut Self {
1002         self.0.create(create);
1003         self
1004     }
1005 
1006     /// Sets the option to create a new file, failing if it already exists.
1007     ///
1008     /// No file is allowed to exist at the target location, also no (dangling) symlink. In this
1009     /// way, if the call succeeds, the file returned is guaranteed to be new.
1010     ///
1011     /// This option is useful because it is atomic. Otherwise between checking
1012     /// whether a file exists and creating a new one, the file may have been
1013     /// created by another process (a TOCTOU race condition / attack).
1014     ///
1015     /// If `.create_new(true)` is set, [`.create()`] and [`.truncate()`] are
1016     /// ignored.
1017     ///
1018     /// The file must be opened with write or append access in order to create
1019     /// a new file.
1020     ///
1021     /// [`.create()`]: OpenOptions::create
1022     /// [`.truncate()`]: OpenOptions::truncate
1023     ///
1024     /// # Examples
1025     ///
1026     /// ```no_run
1027     /// use std::fs::OpenOptions;
1028     ///
1029     /// let file = OpenOptions::new().write(true)
1030     ///                              .create_new(true)
1031     ///                              .open("foo.txt");
1032     /// ```
1033     #[stable(feature = "expand_open_options2", since = "1.9.0")]
create_new(&mut self, create_new: bool) -> &mut Self1034     pub fn create_new(&mut self, create_new: bool) -> &mut Self {
1035         self.0.create_new(create_new);
1036         self
1037     }
1038 
1039     /// Opens a file at `path` with the options specified by `self`.
1040     ///
1041     /// # Errors
1042     ///
1043     /// This function will return an error under a number of different
1044     /// circumstances. Some of these error conditions are listed here, together
1045     /// with their [`io::ErrorKind`]. The mapping to [`io::ErrorKind`]s is not
1046     /// part of the compatibility contract of the function.
1047     ///
1048     /// * [`NotFound`]: The specified file does not exist and neither `create`
1049     ///   or `create_new` is set.
1050     /// * [`NotFound`]: One of the directory components of the file path does
1051     ///   not exist.
1052     /// * [`PermissionDenied`]: The user lacks permission to get the specified
1053     ///   access rights for the file.
1054     /// * [`PermissionDenied`]: The user lacks permission to open one of the
1055     ///   directory components of the specified path.
1056     /// * [`AlreadyExists`]: `create_new` was specified and the file already
1057     ///   exists.
1058     /// * [`InvalidInput`]: Invalid combinations of open options (truncate
1059     ///   without write access, no access mode set, etc.).
1060     ///
1061     /// The following errors don't match any existing [`io::ErrorKind`] at the moment:
1062     /// * One of the directory components of the specified file path
1063     ///   was not, in fact, a directory.
1064     /// * Filesystem-level errors: full disk, write permission
1065     ///   requested on a read-only file system, exceeded disk quota, too many
1066     ///   open files, too long filename, too many symbolic links in the
1067     ///   specified path (Unix-like systems only), etc.
1068     ///
1069     /// # Examples
1070     ///
1071     /// ```no_run
1072     /// use std::fs::OpenOptions;
1073     ///
1074     /// let file = OpenOptions::new().read(true).open("foo.txt");
1075     /// ```
1076     ///
1077     /// [`AlreadyExists`]: io::ErrorKind::AlreadyExists
1078     /// [`InvalidInput`]: io::ErrorKind::InvalidInput
1079     /// [`NotFound`]: io::ErrorKind::NotFound
1080     /// [`PermissionDenied`]: io::ErrorKind::PermissionDenied
1081     #[stable(feature = "rust1", since = "1.0.0")]
open<P: AsRef<Path>>(&self, path: P) -> io::Result<File>1082     pub fn open<P: AsRef<Path>>(&self, path: P) -> io::Result<File> {
1083         self._open(path.as_ref())
1084     }
1085 
_open(&self, path: &Path) -> io::Result<File>1086     fn _open(&self, path: &Path) -> io::Result<File> {
1087         fs_imp::File::open(path, &self.0).map(|inner| File { inner })
1088     }
1089 }
1090 
1091 impl AsInner<fs_imp::OpenOptions> for OpenOptions {
1092     #[inline]
as_inner(&self) -> &fs_imp::OpenOptions1093     fn as_inner(&self) -> &fs_imp::OpenOptions {
1094         &self.0
1095     }
1096 }
1097 
1098 impl AsInnerMut<fs_imp::OpenOptions> for OpenOptions {
1099     #[inline]
as_inner_mut(&mut self) -> &mut fs_imp::OpenOptions1100     fn as_inner_mut(&mut self) -> &mut fs_imp::OpenOptions {
1101         &mut self.0
1102     }
1103 }
1104 
1105 impl Metadata {
1106     /// Returns the file type for this metadata.
1107     ///
1108     /// # Examples
1109     ///
1110     /// ```no_run
1111     /// fn main() -> std::io::Result<()> {
1112     ///     use std::fs;
1113     ///
1114     ///     let metadata = fs::metadata("foo.txt")?;
1115     ///
1116     ///     println!("{:?}", metadata.file_type());
1117     ///     Ok(())
1118     /// }
1119     /// ```
1120     #[must_use]
1121     #[stable(feature = "file_type", since = "1.1.0")]
file_type(&self) -> FileType1122     pub fn file_type(&self) -> FileType {
1123         FileType(self.0.file_type())
1124     }
1125 
1126     /// Returns `true` if this metadata is for a directory. The
1127     /// result is mutually exclusive to the result of
1128     /// [`Metadata::is_file`], and will be false for symlink metadata
1129     /// obtained from [`symlink_metadata`].
1130     ///
1131     /// # Examples
1132     ///
1133     /// ```no_run
1134     /// fn main() -> std::io::Result<()> {
1135     ///     use std::fs;
1136     ///
1137     ///     let metadata = fs::metadata("foo.txt")?;
1138     ///
1139     ///     assert!(!metadata.is_dir());
1140     ///     Ok(())
1141     /// }
1142     /// ```
1143     #[must_use]
1144     #[stable(feature = "rust1", since = "1.0.0")]
is_dir(&self) -> bool1145     pub fn is_dir(&self) -> bool {
1146         self.file_type().is_dir()
1147     }
1148 
1149     /// Returns `true` if this metadata is for a regular file. The
1150     /// result is mutually exclusive to the result of
1151     /// [`Metadata::is_dir`], and will be false for symlink metadata
1152     /// obtained from [`symlink_metadata`].
1153     ///
1154     /// When the goal is simply to read from (or write to) the source, the most
1155     /// reliable way to test the source can be read (or written to) is to open
1156     /// it. Only using `is_file` can break workflows like `diff <( prog_a )` on
1157     /// a Unix-like system for example. See [`File::open`] or
1158     /// [`OpenOptions::open`] for more information.
1159     ///
1160     /// # Examples
1161     ///
1162     /// ```no_run
1163     /// use std::fs;
1164     ///
1165     /// fn main() -> std::io::Result<()> {
1166     ///     let metadata = fs::metadata("foo.txt")?;
1167     ///
1168     ///     assert!(metadata.is_file());
1169     ///     Ok(())
1170     /// }
1171     /// ```
1172     #[must_use]
1173     #[stable(feature = "rust1", since = "1.0.0")]
is_file(&self) -> bool1174     pub fn is_file(&self) -> bool {
1175         self.file_type().is_file()
1176     }
1177 
1178     /// Returns `true` if this metadata is for a symbolic link.
1179     ///
1180     /// # Examples
1181     ///
1182     #[cfg_attr(unix, doc = "```no_run")]
1183     #[cfg_attr(not(unix), doc = "```ignore")]
1184     /// use std::fs;
1185     /// use std::path::Path;
1186     /// use std::os::unix::fs::symlink;
1187     ///
1188     /// fn main() -> std::io::Result<()> {
1189     ///     let link_path = Path::new("link");
1190     ///     symlink("/origin_does_not_exist/", link_path)?;
1191     ///
1192     ///     let metadata = fs::symlink_metadata(link_path)?;
1193     ///
1194     ///     assert!(metadata.is_symlink());
1195     ///     Ok(())
1196     /// }
1197     /// ```
1198     #[must_use]
1199     #[stable(feature = "is_symlink", since = "1.58.0")]
is_symlink(&self) -> bool1200     pub fn is_symlink(&self) -> bool {
1201         self.file_type().is_symlink()
1202     }
1203 
1204     /// Returns the size of the file, in bytes, this metadata is for.
1205     ///
1206     /// # Examples
1207     ///
1208     /// ```no_run
1209     /// use std::fs;
1210     ///
1211     /// fn main() -> std::io::Result<()> {
1212     ///     let metadata = fs::metadata("foo.txt")?;
1213     ///
1214     ///     assert_eq!(0, metadata.len());
1215     ///     Ok(())
1216     /// }
1217     /// ```
1218     #[must_use]
1219     #[stable(feature = "rust1", since = "1.0.0")]
len(&self) -> u641220     pub fn len(&self) -> u64 {
1221         self.0.size()
1222     }
1223 
1224     /// Returns the permissions of the file this metadata is for.
1225     ///
1226     /// # Examples
1227     ///
1228     /// ```no_run
1229     /// use std::fs;
1230     ///
1231     /// fn main() -> std::io::Result<()> {
1232     ///     let metadata = fs::metadata("foo.txt")?;
1233     ///
1234     ///     assert!(!metadata.permissions().readonly());
1235     ///     Ok(())
1236     /// }
1237     /// ```
1238     #[must_use]
1239     #[stable(feature = "rust1", since = "1.0.0")]
permissions(&self) -> Permissions1240     pub fn permissions(&self) -> Permissions {
1241         Permissions(self.0.perm())
1242     }
1243 
1244     /// Returns the last modification time listed in this metadata.
1245     ///
1246     /// The returned value corresponds to the `mtime` field of `stat` on Unix
1247     /// platforms and the `ftLastWriteTime` field on Windows platforms.
1248     ///
1249     /// # Errors
1250     ///
1251     /// This field might not be available on all platforms, and will return an
1252     /// `Err` on platforms where it is not available.
1253     ///
1254     /// # Examples
1255     ///
1256     /// ```no_run
1257     /// use std::fs;
1258     ///
1259     /// fn main() -> std::io::Result<()> {
1260     ///     let metadata = fs::metadata("foo.txt")?;
1261     ///
1262     ///     if let Ok(time) = metadata.modified() {
1263     ///         println!("{time:?}");
1264     ///     } else {
1265     ///         println!("Not supported on this platform");
1266     ///     }
1267     ///     Ok(())
1268     /// }
1269     /// ```
1270     #[stable(feature = "fs_time", since = "1.10.0")]
modified(&self) -> io::Result<SystemTime>1271     pub fn modified(&self) -> io::Result<SystemTime> {
1272         self.0.modified().map(FromInner::from_inner)
1273     }
1274 
1275     /// Returns the last access time of this metadata.
1276     ///
1277     /// The returned value corresponds to the `atime` field of `stat` on Unix
1278     /// platforms and the `ftLastAccessTime` field on Windows platforms.
1279     ///
1280     /// Note that not all platforms will keep this field update in a file's
1281     /// metadata, for example Windows has an option to disable updating this
1282     /// time when files are accessed and Linux similarly has `noatime`.
1283     ///
1284     /// # Errors
1285     ///
1286     /// This field might not be available on all platforms, and will return an
1287     /// `Err` on platforms where it is not available.
1288     ///
1289     /// # Examples
1290     ///
1291     /// ```no_run
1292     /// use std::fs;
1293     ///
1294     /// fn main() -> std::io::Result<()> {
1295     ///     let metadata = fs::metadata("foo.txt")?;
1296     ///
1297     ///     if let Ok(time) = metadata.accessed() {
1298     ///         println!("{time:?}");
1299     ///     } else {
1300     ///         println!("Not supported on this platform");
1301     ///     }
1302     ///     Ok(())
1303     /// }
1304     /// ```
1305     #[stable(feature = "fs_time", since = "1.10.0")]
accessed(&self) -> io::Result<SystemTime>1306     pub fn accessed(&self) -> io::Result<SystemTime> {
1307         self.0.accessed().map(FromInner::from_inner)
1308     }
1309 
1310     /// Returns the creation time listed in this metadata.
1311     ///
1312     /// The returned value corresponds to the `btime` field of `statx` on
1313     /// Linux kernel starting from to 4.11, the `birthtime` field of `stat` on other
1314     /// Unix platforms, and the `ftCreationTime` field on Windows platforms.
1315     ///
1316     /// # Errors
1317     ///
1318     /// This field might not be available on all platforms, and will return an
1319     /// `Err` on platforms or filesystems where it is not available.
1320     ///
1321     /// # Examples
1322     ///
1323     /// ```no_run
1324     /// use std::fs;
1325     ///
1326     /// fn main() -> std::io::Result<()> {
1327     ///     let metadata = fs::metadata("foo.txt")?;
1328     ///
1329     ///     if let Ok(time) = metadata.created() {
1330     ///         println!("{time:?}");
1331     ///     } else {
1332     ///         println!("Not supported on this platform or filesystem");
1333     ///     }
1334     ///     Ok(())
1335     /// }
1336     /// ```
1337     #[stable(feature = "fs_time", since = "1.10.0")]
created(&self) -> io::Result<SystemTime>1338     pub fn created(&self) -> io::Result<SystemTime> {
1339         self.0.created().map(FromInner::from_inner)
1340     }
1341 }
1342 
1343 #[stable(feature = "std_debug", since = "1.16.0")]
1344 impl fmt::Debug for Metadata {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1345     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1346         f.debug_struct("Metadata")
1347             .field("file_type", &self.file_type())
1348             .field("is_dir", &self.is_dir())
1349             .field("is_file", &self.is_file())
1350             .field("permissions", &self.permissions())
1351             .field("modified", &self.modified())
1352             .field("accessed", &self.accessed())
1353             .field("created", &self.created())
1354             .finish_non_exhaustive()
1355     }
1356 }
1357 
1358 impl AsInner<fs_imp::FileAttr> for Metadata {
1359     #[inline]
as_inner(&self) -> &fs_imp::FileAttr1360     fn as_inner(&self) -> &fs_imp::FileAttr {
1361         &self.0
1362     }
1363 }
1364 
1365 impl FromInner<fs_imp::FileAttr> for Metadata {
from_inner(attr: fs_imp::FileAttr) -> Metadata1366     fn from_inner(attr: fs_imp::FileAttr) -> Metadata {
1367         Metadata(attr)
1368     }
1369 }
1370 
1371 impl FileTimes {
1372     /// Create a new `FileTimes` with no times set.
1373     ///
1374     /// Using the resulting `FileTimes` in [`File::set_times`] will not modify any timestamps.
1375     #[unstable(feature = "file_set_times", issue = "98245")]
new() -> Self1376     pub fn new() -> Self {
1377         Self::default()
1378     }
1379 
1380     /// Set the last access time of a file.
1381     #[unstable(feature = "file_set_times", issue = "98245")]
set_accessed(mut self, t: SystemTime) -> Self1382     pub fn set_accessed(mut self, t: SystemTime) -> Self {
1383         self.0.set_accessed(t.into_inner());
1384         self
1385     }
1386 
1387     /// Set the last modified time of a file.
1388     #[unstable(feature = "file_set_times", issue = "98245")]
set_modified(mut self, t: SystemTime) -> Self1389     pub fn set_modified(mut self, t: SystemTime) -> Self {
1390         self.0.set_modified(t.into_inner());
1391         self
1392     }
1393 }
1394 
1395 impl AsInnerMut<fs_imp::FileTimes> for FileTimes {
as_inner_mut(&mut self) -> &mut fs_imp::FileTimes1396     fn as_inner_mut(&mut self) -> &mut fs_imp::FileTimes {
1397         &mut self.0
1398     }
1399 }
1400 
1401 // For implementing OS extension traits in `std::os`
1402 #[unstable(feature = "file_set_times", issue = "98245")]
1403 impl Sealed for FileTimes {}
1404 
1405 impl Permissions {
1406     /// Returns `true` if these permissions describe a readonly (unwritable) file.
1407     ///
1408     /// # Note
1409     ///
1410     /// This function does not take Access Control Lists (ACLs) or Unix group
1411     /// membership into account.
1412     ///
1413     /// # Windows
1414     ///
1415     /// On Windows this returns [`FILE_ATTRIBUTE_READONLY`](https://docs.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants).
1416     /// If `FILE_ATTRIBUTE_READONLY` is set then writes to the file will fail
1417     /// but the user may still have permission to change this flag. If
1418     /// `FILE_ATTRIBUTE_READONLY` is *not* set then writes may still fail due
1419     /// to lack of write permission.
1420     /// The behavior of this attribute for directories depends on the Windows
1421     /// version.
1422     ///
1423     /// # Unix (including macOS)
1424     ///
1425     /// On Unix-based platforms this checks if *any* of the owner, group or others
1426     /// write permission bits are set. It does not check if the current
1427     /// user is in the file's assigned group. It also does not check ACLs.
1428     /// Therefore even if this returns true you may not be able to write to the
1429     /// file, and vice versa. The [`PermissionsExt`] trait gives direct access
1430     /// to the permission bits but also does not read ACLs. If you need to
1431     /// accurately know whether or not a file is writable use the `access()`
1432     /// function from libc.
1433     ///
1434     /// [`PermissionsExt`]: crate::os::unix::fs::PermissionsExt
1435     ///
1436     /// # Examples
1437     ///
1438     /// ```no_run
1439     /// use std::fs::File;
1440     ///
1441     /// fn main() -> std::io::Result<()> {
1442     ///     let mut f = File::create("foo.txt")?;
1443     ///     let metadata = f.metadata()?;
1444     ///
1445     ///     assert_eq!(false, metadata.permissions().readonly());
1446     ///     Ok(())
1447     /// }
1448     /// ```
1449     #[must_use = "call `set_readonly` to modify the readonly flag"]
1450     #[stable(feature = "rust1", since = "1.0.0")]
readonly(&self) -> bool1451     pub fn readonly(&self) -> bool {
1452         self.0.readonly()
1453     }
1454 
1455     /// Modifies the readonly flag for this set of permissions. If the
1456     /// `readonly` argument is `true`, using the resulting `Permission` will
1457     /// update file permissions to forbid writing. Conversely, if it's `false`,
1458     /// using the resulting `Permission` will update file permissions to allow
1459     /// writing.
1460     ///
1461     /// This operation does **not** modify the files attributes. This only
1462     /// changes the in-memory value of these attributes for this `Permissions`
1463     /// instance. To modify the files attributes use the [`set_permissions`]
1464     /// function which commits these attribute changes to the file.
1465     ///
1466     /// # Note
1467     ///
1468     /// `set_readonly(false)` makes the file *world-writable* on Unix.
1469     /// You can use the [`PermissionsExt`] trait on Unix to avoid this issue.
1470     ///
1471     /// It also does not take Access Control Lists (ACLs) or Unix group
1472     /// membership into account.
1473     ///
1474     /// # Windows
1475     ///
1476     /// On Windows this sets or clears [`FILE_ATTRIBUTE_READONLY`](https://docs.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants).
1477     /// If `FILE_ATTRIBUTE_READONLY` is set then writes to the file will fail
1478     /// but the user may still have permission to change this flag. If
1479     /// `FILE_ATTRIBUTE_READONLY` is *not* set then the write may still fail if
1480     /// the user does not have permission to write to the file.
1481     ///
1482     /// In Windows 7 and earlier this attribute prevents deleting empty
1483     /// directories. It does not prevent modifying the directory contents.
1484     /// On later versions of Windows this attribute is ignored for directories.
1485     ///
1486     /// # Unix (including macOS)
1487     ///
1488     /// On Unix-based platforms this sets or clears the write access bit for
1489     /// the owner, group *and* others, equivalent to `chmod a+w <file>`
1490     /// or `chmod a-w <file>` respectively. The latter will grant write access
1491     /// to all users! You can use the [`PermissionsExt`] trait on Unix
1492     /// to avoid this issue.
1493     ///
1494     /// [`PermissionsExt`]: crate::os::unix::fs::PermissionsExt
1495     ///
1496     /// # Examples
1497     ///
1498     /// ```no_run
1499     /// use std::fs::File;
1500     ///
1501     /// fn main() -> std::io::Result<()> {
1502     ///     let f = File::create("foo.txt")?;
1503     ///     let metadata = f.metadata()?;
1504     ///     let mut permissions = metadata.permissions();
1505     ///
1506     ///     permissions.set_readonly(true);
1507     ///
1508     ///     // filesystem doesn't change, only the in memory state of the
1509     ///     // readonly permission
1510     ///     assert_eq!(false, metadata.permissions().readonly());
1511     ///
1512     ///     // just this particular `permissions`.
1513     ///     assert_eq!(true, permissions.readonly());
1514     ///     Ok(())
1515     /// }
1516     /// ```
1517     #[stable(feature = "rust1", since = "1.0.0")]
set_readonly(&mut self, readonly: bool)1518     pub fn set_readonly(&mut self, readonly: bool) {
1519         self.0.set_readonly(readonly)
1520     }
1521 }
1522 
1523 impl FileType {
1524     /// Tests whether this file type represents a directory. The
1525     /// result is mutually exclusive to the results of
1526     /// [`is_file`] and [`is_symlink`]; only zero or one of these
1527     /// tests may pass.
1528     ///
1529     /// [`is_file`]: FileType::is_file
1530     /// [`is_symlink`]: FileType::is_symlink
1531     ///
1532     /// # Examples
1533     ///
1534     /// ```no_run
1535     /// fn main() -> std::io::Result<()> {
1536     ///     use std::fs;
1537     ///
1538     ///     let metadata = fs::metadata("foo.txt")?;
1539     ///     let file_type = metadata.file_type();
1540     ///
1541     ///     assert_eq!(file_type.is_dir(), false);
1542     ///     Ok(())
1543     /// }
1544     /// ```
1545     #[must_use]
1546     #[stable(feature = "file_type", since = "1.1.0")]
is_dir(&self) -> bool1547     pub fn is_dir(&self) -> bool {
1548         self.0.is_dir()
1549     }
1550 
1551     /// Tests whether this file type represents a regular file.
1552     /// The result is mutually exclusive to the results of
1553     /// [`is_dir`] and [`is_symlink`]; only zero or one of these
1554     /// tests may pass.
1555     ///
1556     /// When the goal is simply to read from (or write to) the source, the most
1557     /// reliable way to test the source can be read (or written to) is to open
1558     /// it. Only using `is_file` can break workflows like `diff <( prog_a )` on
1559     /// a Unix-like system for example. See [`File::open`] or
1560     /// [`OpenOptions::open`] for more information.
1561     ///
1562     /// [`is_dir`]: FileType::is_dir
1563     /// [`is_symlink`]: FileType::is_symlink
1564     ///
1565     /// # Examples
1566     ///
1567     /// ```no_run
1568     /// fn main() -> std::io::Result<()> {
1569     ///     use std::fs;
1570     ///
1571     ///     let metadata = fs::metadata("foo.txt")?;
1572     ///     let file_type = metadata.file_type();
1573     ///
1574     ///     assert_eq!(file_type.is_file(), true);
1575     ///     Ok(())
1576     /// }
1577     /// ```
1578     #[must_use]
1579     #[stable(feature = "file_type", since = "1.1.0")]
is_file(&self) -> bool1580     pub fn is_file(&self) -> bool {
1581         self.0.is_file()
1582     }
1583 
1584     /// Tests whether this file type represents a symbolic link.
1585     /// The result is mutually exclusive to the results of
1586     /// [`is_dir`] and [`is_file`]; only zero or one of these
1587     /// tests may pass.
1588     ///
1589     /// The underlying [`Metadata`] struct needs to be retrieved
1590     /// with the [`fs::symlink_metadata`] function and not the
1591     /// [`fs::metadata`] function. The [`fs::metadata`] function
1592     /// follows symbolic links, so [`is_symlink`] would always
1593     /// return `false` for the target file.
1594     ///
1595     /// [`fs::metadata`]: metadata
1596     /// [`fs::symlink_metadata`]: symlink_metadata
1597     /// [`is_dir`]: FileType::is_dir
1598     /// [`is_file`]: FileType::is_file
1599     /// [`is_symlink`]: FileType::is_symlink
1600     ///
1601     /// # Examples
1602     ///
1603     /// ```no_run
1604     /// use std::fs;
1605     ///
1606     /// fn main() -> std::io::Result<()> {
1607     ///     let metadata = fs::symlink_metadata("foo.txt")?;
1608     ///     let file_type = metadata.file_type();
1609     ///
1610     ///     assert_eq!(file_type.is_symlink(), false);
1611     ///     Ok(())
1612     /// }
1613     /// ```
1614     #[must_use]
1615     #[stable(feature = "file_type", since = "1.1.0")]
is_symlink(&self) -> bool1616     pub fn is_symlink(&self) -> bool {
1617         self.0.is_symlink()
1618     }
1619 }
1620 
1621 impl AsInner<fs_imp::FileType> for FileType {
1622     #[inline]
as_inner(&self) -> &fs_imp::FileType1623     fn as_inner(&self) -> &fs_imp::FileType {
1624         &self.0
1625     }
1626 }
1627 
1628 impl FromInner<fs_imp::FilePermissions> for Permissions {
from_inner(f: fs_imp::FilePermissions) -> Permissions1629     fn from_inner(f: fs_imp::FilePermissions) -> Permissions {
1630         Permissions(f)
1631     }
1632 }
1633 
1634 impl AsInner<fs_imp::FilePermissions> for Permissions {
1635     #[inline]
as_inner(&self) -> &fs_imp::FilePermissions1636     fn as_inner(&self) -> &fs_imp::FilePermissions {
1637         &self.0
1638     }
1639 }
1640 
1641 #[stable(feature = "rust1", since = "1.0.0")]
1642 impl Iterator for ReadDir {
1643     type Item = io::Result<DirEntry>;
1644 
next(&mut self) -> Option<io::Result<DirEntry>>1645     fn next(&mut self) -> Option<io::Result<DirEntry>> {
1646         self.0.next().map(|entry| entry.map(DirEntry))
1647     }
1648 }
1649 
1650 impl DirEntry {
1651     /// Returns the full path to the file that this entry represents.
1652     ///
1653     /// The full path is created by joining the original path to `read_dir`
1654     /// with the filename of this entry.
1655     ///
1656     /// # Examples
1657     ///
1658     /// ```no_run
1659     /// use std::fs;
1660     ///
1661     /// fn main() -> std::io::Result<()> {
1662     ///     for entry in fs::read_dir(".")? {
1663     ///         let dir = entry?;
1664     ///         println!("{:?}", dir.path());
1665     ///     }
1666     ///     Ok(())
1667     /// }
1668     /// ```
1669     ///
1670     /// This prints output like:
1671     ///
1672     /// ```text
1673     /// "./whatever.txt"
1674     /// "./foo.html"
1675     /// "./hello_world.rs"
1676     /// ```
1677     ///
1678     /// The exact text, of course, depends on what files you have in `.`.
1679     #[must_use]
1680     #[stable(feature = "rust1", since = "1.0.0")]
path(&self) -> PathBuf1681     pub fn path(&self) -> PathBuf {
1682         self.0.path()
1683     }
1684 
1685     /// Returns the metadata for the file that this entry points at.
1686     ///
1687     /// This function will not traverse symlinks if this entry points at a
1688     /// symlink. To traverse symlinks use [`fs::metadata`] or [`fs::File::metadata`].
1689     ///
1690     /// [`fs::metadata`]: metadata
1691     /// [`fs::File::metadata`]: File::metadata
1692     ///
1693     /// # Platform-specific behavior
1694     ///
1695     /// On Windows this function is cheap to call (no extra system calls
1696     /// needed), but on Unix platforms this function is the equivalent of
1697     /// calling `symlink_metadata` on the path.
1698     ///
1699     /// # Examples
1700     ///
1701     /// ```
1702     /// use std::fs;
1703     ///
1704     /// if let Ok(entries) = fs::read_dir(".") {
1705     ///     for entry in entries {
1706     ///         if let Ok(entry) = entry {
1707     ///             // Here, `entry` is a `DirEntry`.
1708     ///             if let Ok(metadata) = entry.metadata() {
1709     ///                 // Now let's show our entry's permissions!
1710     ///                 println!("{:?}: {:?}", entry.path(), metadata.permissions());
1711     ///             } else {
1712     ///                 println!("Couldn't get metadata for {:?}", entry.path());
1713     ///             }
1714     ///         }
1715     ///     }
1716     /// }
1717     /// ```
1718     #[stable(feature = "dir_entry_ext", since = "1.1.0")]
metadata(&self) -> io::Result<Metadata>1719     pub fn metadata(&self) -> io::Result<Metadata> {
1720         self.0.metadata().map(Metadata)
1721     }
1722 
1723     /// Returns the file type for the file that this entry points at.
1724     ///
1725     /// This function will not traverse symlinks if this entry points at a
1726     /// symlink.
1727     ///
1728     /// # Platform-specific behavior
1729     ///
1730     /// On Windows and most Unix platforms this function is free (no extra
1731     /// system calls needed), but some Unix platforms may require the equivalent
1732     /// call to `symlink_metadata` to learn about the target file type.
1733     ///
1734     /// # Examples
1735     ///
1736     /// ```
1737     /// use std::fs;
1738     ///
1739     /// if let Ok(entries) = fs::read_dir(".") {
1740     ///     for entry in entries {
1741     ///         if let Ok(entry) = entry {
1742     ///             // Here, `entry` is a `DirEntry`.
1743     ///             if let Ok(file_type) = entry.file_type() {
1744     ///                 // Now let's show our entry's file type!
1745     ///                 println!("{:?}: {:?}", entry.path(), file_type);
1746     ///             } else {
1747     ///                 println!("Couldn't get file type for {:?}", entry.path());
1748     ///             }
1749     ///         }
1750     ///     }
1751     /// }
1752     /// ```
1753     #[stable(feature = "dir_entry_ext", since = "1.1.0")]
file_type(&self) -> io::Result<FileType>1754     pub fn file_type(&self) -> io::Result<FileType> {
1755         self.0.file_type().map(FileType)
1756     }
1757 
1758     /// Returns the file name of this directory entry without any
1759     /// leading path component(s).
1760     ///
1761     /// As an example,
1762     /// the output of the function will result in "foo" for all the following paths:
1763     /// - "./foo"
1764     /// - "/the/foo"
1765     /// - "../../foo"
1766     ///
1767     /// # Examples
1768     ///
1769     /// ```
1770     /// use std::fs;
1771     ///
1772     /// if let Ok(entries) = fs::read_dir(".") {
1773     ///     for entry in entries {
1774     ///         if let Ok(entry) = entry {
1775     ///             // Here, `entry` is a `DirEntry`.
1776     ///             println!("{:?}", entry.file_name());
1777     ///         }
1778     ///     }
1779     /// }
1780     /// ```
1781     #[must_use]
1782     #[stable(feature = "dir_entry_ext", since = "1.1.0")]
file_name(&self) -> OsString1783     pub fn file_name(&self) -> OsString {
1784         self.0.file_name()
1785     }
1786 }
1787 
1788 #[stable(feature = "dir_entry_debug", since = "1.13.0")]
1789 impl fmt::Debug for DirEntry {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1790     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1791         f.debug_tuple("DirEntry").field(&self.path()).finish()
1792     }
1793 }
1794 
1795 impl AsInner<fs_imp::DirEntry> for DirEntry {
1796     #[inline]
as_inner(&self) -> &fs_imp::DirEntry1797     fn as_inner(&self) -> &fs_imp::DirEntry {
1798         &self.0
1799     }
1800 }
1801 
1802 /// Removes a file from the filesystem.
1803 ///
1804 /// Note that there is no
1805 /// guarantee that the file is immediately deleted (e.g., depending on
1806 /// platform, other open file descriptors may prevent immediate removal).
1807 ///
1808 /// # Platform-specific behavior
1809 ///
1810 /// This function currently corresponds to the `unlink` function on Unix
1811 /// and the `DeleteFile` function on Windows.
1812 /// Note that, this [may change in the future][changes].
1813 ///
1814 /// [changes]: io#platform-specific-behavior
1815 ///
1816 /// # Errors
1817 ///
1818 /// This function will return an error in the following situations, but is not
1819 /// limited to just these cases:
1820 ///
1821 /// * `path` points to a directory.
1822 /// * The file doesn't exist.
1823 /// * The user lacks permissions to remove the file.
1824 ///
1825 /// # Examples
1826 ///
1827 /// ```no_run
1828 /// use std::fs;
1829 ///
1830 /// fn main() -> std::io::Result<()> {
1831 ///     fs::remove_file("a.txt")?;
1832 ///     Ok(())
1833 /// }
1834 /// ```
1835 #[stable(feature = "rust1", since = "1.0.0")]
remove_file<P: AsRef<Path>>(path: P) -> io::Result<()>1836 pub fn remove_file<P: AsRef<Path>>(path: P) -> io::Result<()> {
1837     fs_imp::unlink(path.as_ref())
1838 }
1839 
1840 /// Given a path, query the file system to get information about a file,
1841 /// directory, etc.
1842 ///
1843 /// This function will traverse symbolic links to query information about the
1844 /// destination file.
1845 ///
1846 /// # Platform-specific behavior
1847 ///
1848 /// This function currently corresponds to the `stat` function on Unix
1849 /// and the `GetFileInformationByHandle` function on Windows.
1850 /// Note that, this [may change in the future][changes].
1851 ///
1852 /// [changes]: io#platform-specific-behavior
1853 ///
1854 /// # Errors
1855 ///
1856 /// This function will return an error in the following situations, but is not
1857 /// limited to just these cases:
1858 ///
1859 /// * The user lacks permissions to perform `metadata` call on `path`.
1860 /// * `path` does not exist.
1861 ///
1862 /// # Examples
1863 ///
1864 /// ```rust,no_run
1865 /// use std::fs;
1866 ///
1867 /// fn main() -> std::io::Result<()> {
1868 ///     let attr = fs::metadata("/some/file/path.txt")?;
1869 ///     // inspect attr ...
1870 ///     Ok(())
1871 /// }
1872 /// ```
1873 #[stable(feature = "rust1", since = "1.0.0")]
metadata<P: AsRef<Path>>(path: P) -> io::Result<Metadata>1874 pub fn metadata<P: AsRef<Path>>(path: P) -> io::Result<Metadata> {
1875     fs_imp::stat(path.as_ref()).map(Metadata)
1876 }
1877 
1878 /// Query the metadata about a file without following symlinks.
1879 ///
1880 /// # Platform-specific behavior
1881 ///
1882 /// This function currently corresponds to the `lstat` function on Unix
1883 /// and the `GetFileInformationByHandle` function on Windows.
1884 /// Note that, this [may change in the future][changes].
1885 ///
1886 /// [changes]: io#platform-specific-behavior
1887 ///
1888 /// # Errors
1889 ///
1890 /// This function will return an error in the following situations, but is not
1891 /// limited to just these cases:
1892 ///
1893 /// * The user lacks permissions to perform `metadata` call on `path`.
1894 /// * `path` does not exist.
1895 ///
1896 /// # Examples
1897 ///
1898 /// ```rust,no_run
1899 /// use std::fs;
1900 ///
1901 /// fn main() -> std::io::Result<()> {
1902 ///     let attr = fs::symlink_metadata("/some/file/path.txt")?;
1903 ///     // inspect attr ...
1904 ///     Ok(())
1905 /// }
1906 /// ```
1907 #[stable(feature = "symlink_metadata", since = "1.1.0")]
symlink_metadata<P: AsRef<Path>>(path: P) -> io::Result<Metadata>1908 pub fn symlink_metadata<P: AsRef<Path>>(path: P) -> io::Result<Metadata> {
1909     fs_imp::lstat(path.as_ref()).map(Metadata)
1910 }
1911 
1912 /// Rename a file or directory to a new name, replacing the original file if
1913 /// `to` already exists.
1914 ///
1915 /// This will not work if the new name is on a different mount point.
1916 ///
1917 /// # Platform-specific behavior
1918 ///
1919 /// This function currently corresponds to the `rename` function on Unix
1920 /// and the `MoveFileEx` function with the `MOVEFILE_REPLACE_EXISTING` flag on Windows.
1921 ///
1922 /// Because of this, the behavior when both `from` and `to` exist differs. On
1923 /// Unix, if `from` is a directory, `to` must also be an (empty) directory. If
1924 /// `from` is not a directory, `to` must also be not a directory. In contrast,
1925 /// on Windows, `from` can be anything, but `to` must *not* be a directory.
1926 ///
1927 /// Note that, this [may change in the future][changes].
1928 ///
1929 /// [changes]: io#platform-specific-behavior
1930 ///
1931 /// # Errors
1932 ///
1933 /// This function will return an error in the following situations, but is not
1934 /// limited to just these cases:
1935 ///
1936 /// * `from` does not exist.
1937 /// * The user lacks permissions to view contents.
1938 /// * `from` and `to` are on separate filesystems.
1939 ///
1940 /// # Examples
1941 ///
1942 /// ```no_run
1943 /// use std::fs;
1944 ///
1945 /// fn main() -> std::io::Result<()> {
1946 ///     fs::rename("a.txt", "b.txt")?; // Rename a.txt to b.txt
1947 ///     Ok(())
1948 /// }
1949 /// ```
1950 #[stable(feature = "rust1", since = "1.0.0")]
rename<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()>1951 pub fn rename<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()> {
1952     fs_imp::rename(from.as_ref(), to.as_ref())
1953 }
1954 
1955 /// Copies the contents of one file to another. This function will also
1956 /// copy the permission bits of the original file to the destination file.
1957 ///
1958 /// This function will **overwrite** the contents of `to`.
1959 ///
1960 /// Note that if `from` and `to` both point to the same file, then the file
1961 /// will likely get truncated by this operation.
1962 ///
1963 /// On success, the total number of bytes copied is returned and it is equal to
1964 /// the length of the `to` file as reported by `metadata`.
1965 ///
1966 /// If you want to copy the contents of one file to another and you’re
1967 /// working with [`File`]s, see the [`io::copy()`] function.
1968 ///
1969 /// # Platform-specific behavior
1970 ///
1971 /// This function currently corresponds to the `open` function in Unix
1972 /// with `O_RDONLY` for `from` and `O_WRONLY`, `O_CREAT`, and `O_TRUNC` for `to`.
1973 /// `O_CLOEXEC` is set for returned file descriptors.
1974 ///
1975 /// On Linux (including Android), this function attempts to use `copy_file_range(2)`,
1976 /// and falls back to reading and writing if that is not possible.
1977 ///
1978 /// On Windows, this function currently corresponds to `CopyFileEx`. Alternate
1979 /// NTFS streams are copied but only the size of the main stream is returned by
1980 /// this function.
1981 ///
1982 /// On MacOS, this function corresponds to `fclonefileat` and `fcopyfile`.
1983 ///
1984 /// Note that platform-specific behavior [may change in the future][changes].
1985 ///
1986 /// [changes]: io#platform-specific-behavior
1987 ///
1988 /// # Errors
1989 ///
1990 /// This function will return an error in the following situations, but is not
1991 /// limited to just these cases:
1992 ///
1993 /// * `from` is neither a regular file nor a symlink to a regular file.
1994 /// * `from` does not exist.
1995 /// * The current process does not have the permission rights to read
1996 ///   `from` or write `to`.
1997 ///
1998 /// # Examples
1999 ///
2000 /// ```no_run
2001 /// use std::fs;
2002 ///
2003 /// fn main() -> std::io::Result<()> {
2004 ///     fs::copy("foo.txt", "bar.txt")?;  // Copy foo.txt to bar.txt
2005 ///     Ok(())
2006 /// }
2007 /// ```
2008 #[stable(feature = "rust1", since = "1.0.0")]
copy<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<u64>2009 pub fn copy<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<u64> {
2010     fs_imp::copy(from.as_ref(), to.as_ref())
2011 }
2012 
2013 /// Creates a new hard link on the filesystem.
2014 ///
2015 /// The `link` path will be a link pointing to the `original` path. Note that
2016 /// systems often require these two paths to both be located on the same
2017 /// filesystem.
2018 ///
2019 /// If `original` names a symbolic link, it is platform-specific whether the
2020 /// symbolic link is followed. On platforms where it's possible to not follow
2021 /// it, it is not followed, and the created hard link points to the symbolic
2022 /// link itself.
2023 ///
2024 /// # Platform-specific behavior
2025 ///
2026 /// This function currently corresponds the `CreateHardLink` function on Windows.
2027 /// On most Unix systems, it corresponds to the `linkat` function with no flags.
2028 /// On Android, VxWorks, and Redox, it instead corresponds to the `link` function.
2029 /// On MacOS, it uses the `linkat` function if it is available, but on very old
2030 /// systems where `linkat` is not available, `link` is selected at runtime instead.
2031 /// Note that, this [may change in the future][changes].
2032 ///
2033 /// [changes]: io#platform-specific-behavior
2034 ///
2035 /// # Errors
2036 ///
2037 /// This function will return an error in the following situations, but is not
2038 /// limited to just these cases:
2039 ///
2040 /// * The `original` path is not a file or doesn't exist.
2041 ///
2042 /// # Examples
2043 ///
2044 /// ```no_run
2045 /// use std::fs;
2046 ///
2047 /// fn main() -> std::io::Result<()> {
2048 ///     fs::hard_link("a.txt", "b.txt")?; // Hard link a.txt to b.txt
2049 ///     Ok(())
2050 /// }
2051 /// ```
2052 #[stable(feature = "rust1", since = "1.0.0")]
hard_link<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) -> io::Result<()>2053 pub fn hard_link<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) -> io::Result<()> {
2054     fs_imp::link(original.as_ref(), link.as_ref())
2055 }
2056 
2057 /// Creates a new symbolic link on the filesystem.
2058 ///
2059 /// The `link` path will be a symbolic link pointing to the `original` path.
2060 /// On Windows, this will be a file symlink, not a directory symlink;
2061 /// for this reason, the platform-specific [`std::os::unix::fs::symlink`]
2062 /// and [`std::os::windows::fs::symlink_file`] or [`symlink_dir`] should be
2063 /// used instead to make the intent explicit.
2064 ///
2065 /// [`std::os::unix::fs::symlink`]: crate::os::unix::fs::symlink
2066 /// [`std::os::windows::fs::symlink_file`]: crate::os::windows::fs::symlink_file
2067 /// [`symlink_dir`]: crate::os::windows::fs::symlink_dir
2068 ///
2069 /// # Examples
2070 ///
2071 /// ```no_run
2072 /// use std::fs;
2073 ///
2074 /// fn main() -> std::io::Result<()> {
2075 ///     fs::soft_link("a.txt", "b.txt")?;
2076 ///     Ok(())
2077 /// }
2078 /// ```
2079 #[stable(feature = "rust1", since = "1.0.0")]
2080 #[deprecated(
2081     since = "1.1.0",
2082     note = "replaced with std::os::unix::fs::symlink and \
2083             std::os::windows::fs::{symlink_file, symlink_dir}"
2084 )]
soft_link<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) -> io::Result<()>2085 pub fn soft_link<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) -> io::Result<()> {
2086     fs_imp::symlink(original.as_ref(), link.as_ref())
2087 }
2088 
2089 /// Reads a symbolic link, returning the file that the link points to.
2090 ///
2091 /// # Platform-specific behavior
2092 ///
2093 /// This function currently corresponds to the `readlink` function on Unix
2094 /// and the `CreateFile` function with `FILE_FLAG_OPEN_REPARSE_POINT` and
2095 /// `FILE_FLAG_BACKUP_SEMANTICS` flags on Windows.
2096 /// Note that, this [may change in the future][changes].
2097 ///
2098 /// [changes]: io#platform-specific-behavior
2099 ///
2100 /// # Errors
2101 ///
2102 /// This function will return an error in the following situations, but is not
2103 /// limited to just these cases:
2104 ///
2105 /// * `path` is not a symbolic link.
2106 /// * `path` does not exist.
2107 ///
2108 /// # Examples
2109 ///
2110 /// ```no_run
2111 /// use std::fs;
2112 ///
2113 /// fn main() -> std::io::Result<()> {
2114 ///     let path = fs::read_link("a.txt")?;
2115 ///     Ok(())
2116 /// }
2117 /// ```
2118 #[stable(feature = "rust1", since = "1.0.0")]
read_link<P: AsRef<Path>>(path: P) -> io::Result<PathBuf>2119 pub fn read_link<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
2120     fs_imp::readlink(path.as_ref())
2121 }
2122 
2123 /// Returns the canonical, absolute form of a path with all intermediate
2124 /// components normalized and symbolic links resolved.
2125 ///
2126 /// # Platform-specific behavior
2127 ///
2128 /// This function currently corresponds to the `realpath` function on Unix
2129 /// and the `CreateFile` and `GetFinalPathNameByHandle` functions on Windows.
2130 /// Note that, this [may change in the future][changes].
2131 ///
2132 /// On Windows, this converts the path to use [extended length path][path]
2133 /// syntax, which allows your program to use longer path names, but means you
2134 /// can only join backslash-delimited paths to it, and it may be incompatible
2135 /// with other applications (if passed to the application on the command-line,
2136 /// or written to a file another application may read).
2137 ///
2138 /// [changes]: io#platform-specific-behavior
2139 /// [path]: https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file
2140 ///
2141 /// # Errors
2142 ///
2143 /// This function will return an error in the following situations, but is not
2144 /// limited to just these cases:
2145 ///
2146 /// * `path` does not exist.
2147 /// * A non-final component in path is not a directory.
2148 ///
2149 /// # Examples
2150 ///
2151 /// ```no_run
2152 /// use std::fs;
2153 ///
2154 /// fn main() -> std::io::Result<()> {
2155 ///     let path = fs::canonicalize("../a/../foo.txt")?;
2156 ///     Ok(())
2157 /// }
2158 /// ```
2159 #[doc(alias = "realpath")]
2160 #[doc(alias = "GetFinalPathNameByHandle")]
2161 #[stable(feature = "fs_canonicalize", since = "1.5.0")]
canonicalize<P: AsRef<Path>>(path: P) -> io::Result<PathBuf>2162 pub fn canonicalize<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
2163     fs_imp::canonicalize(path.as_ref())
2164 }
2165 
2166 /// Creates a new, empty directory at the provided path
2167 ///
2168 /// # Platform-specific behavior
2169 ///
2170 /// This function currently corresponds to the `mkdir` function on Unix
2171 /// and the `CreateDirectory` function on Windows.
2172 /// Note that, this [may change in the future][changes].
2173 ///
2174 /// [changes]: io#platform-specific-behavior
2175 ///
2176 /// **NOTE**: If a parent of the given path doesn't exist, this function will
2177 /// return an error. To create a directory and all its missing parents at the
2178 /// same time, use the [`create_dir_all`] function.
2179 ///
2180 /// # Errors
2181 ///
2182 /// This function will return an error in the following situations, but is not
2183 /// limited to just these cases:
2184 ///
2185 /// * User lacks permissions to create directory at `path`.
2186 /// * A parent of the given path doesn't exist. (To create a directory and all
2187 ///   its missing parents at the same time, use the [`create_dir_all`]
2188 ///   function.)
2189 /// * `path` already exists.
2190 ///
2191 /// # Examples
2192 ///
2193 /// ```no_run
2194 /// use std::fs;
2195 ///
2196 /// fn main() -> std::io::Result<()> {
2197 ///     fs::create_dir("/some/dir")?;
2198 ///     Ok(())
2199 /// }
2200 /// ```
2201 #[doc(alias = "mkdir")]
2202 #[stable(feature = "rust1", since = "1.0.0")]
create_dir<P: AsRef<Path>>(path: P) -> io::Result<()>2203 pub fn create_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
2204     DirBuilder::new().create(path.as_ref())
2205 }
2206 
2207 /// Recursively create a directory and all of its parent components if they
2208 /// are missing.
2209 ///
2210 /// # Platform-specific behavior
2211 ///
2212 /// This function currently corresponds to the `mkdir` function on Unix
2213 /// and the `CreateDirectory` function on Windows.
2214 /// Note that, this [may change in the future][changes].
2215 ///
2216 /// [changes]: io#platform-specific-behavior
2217 ///
2218 /// # Errors
2219 ///
2220 /// This function will return an error in the following situations, but is not
2221 /// limited to just these cases:
2222 ///
2223 /// * If any directory in the path specified by `path`
2224 /// does not already exist and it could not be created otherwise. The specific
2225 /// error conditions for when a directory is being created (after it is
2226 /// determined to not exist) are outlined by [`fs::create_dir`].
2227 ///
2228 /// Notable exception is made for situations where any of the directories
2229 /// specified in the `path` could not be created as it was being created concurrently.
2230 /// Such cases are considered to be successful. That is, calling `create_dir_all`
2231 /// concurrently from multiple threads or processes is guaranteed not to fail
2232 /// due to a race condition with itself.
2233 ///
2234 /// [`fs::create_dir`]: create_dir
2235 ///
2236 /// # Examples
2237 ///
2238 /// ```no_run
2239 /// use std::fs;
2240 ///
2241 /// fn main() -> std::io::Result<()> {
2242 ///     fs::create_dir_all("/some/dir")?;
2243 ///     Ok(())
2244 /// }
2245 /// ```
2246 #[stable(feature = "rust1", since = "1.0.0")]
create_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()>2247 pub fn create_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
2248     DirBuilder::new().recursive(true).create(path.as_ref())
2249 }
2250 
2251 /// Removes an empty directory.
2252 ///
2253 /// # Platform-specific behavior
2254 ///
2255 /// This function currently corresponds to the `rmdir` function on Unix
2256 /// and the `RemoveDirectory` function on Windows.
2257 /// Note that, this [may change in the future][changes].
2258 ///
2259 /// [changes]: io#platform-specific-behavior
2260 ///
2261 /// # Errors
2262 ///
2263 /// This function will return an error in the following situations, but is not
2264 /// limited to just these cases:
2265 ///
2266 /// * `path` doesn't exist.
2267 /// * `path` isn't a directory.
2268 /// * The user lacks permissions to remove the directory at the provided `path`.
2269 /// * The directory isn't empty.
2270 ///
2271 /// # Examples
2272 ///
2273 /// ```no_run
2274 /// use std::fs;
2275 ///
2276 /// fn main() -> std::io::Result<()> {
2277 ///     fs::remove_dir("/some/dir")?;
2278 ///     Ok(())
2279 /// }
2280 /// ```
2281 #[doc(alias = "rmdir")]
2282 #[stable(feature = "rust1", since = "1.0.0")]
remove_dir<P: AsRef<Path>>(path: P) -> io::Result<()>2283 pub fn remove_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
2284     fs_imp::rmdir(path.as_ref())
2285 }
2286 
2287 /// Removes a directory at this path, after removing all its contents. Use
2288 /// carefully!
2289 ///
2290 /// This function does **not** follow symbolic links and it will simply remove the
2291 /// symbolic link itself.
2292 ///
2293 /// # Platform-specific behavior
2294 ///
2295 /// This function currently corresponds to `openat`, `fdopendir`, `unlinkat` and `lstat` functions
2296 /// on Unix (except for macOS before version 10.10 and REDOX) and the `CreateFileW`,
2297 /// `GetFileInformationByHandleEx`, `SetFileInformationByHandle`, and `NtCreateFile` functions on
2298 /// Windows. Note that, this [may change in the future][changes].
2299 ///
2300 /// [changes]: io#platform-specific-behavior
2301 ///
2302 /// On macOS before version 10.10 and REDOX, as well as when running in Miri for any target, this
2303 /// function is not protected against time-of-check to time-of-use (TOCTOU) race conditions, and
2304 /// should not be used in security-sensitive code on those platforms. All other platforms are
2305 /// protected.
2306 ///
2307 /// # Errors
2308 ///
2309 /// See [`fs::remove_file`] and [`fs::remove_dir`].
2310 ///
2311 /// `remove_dir_all` will fail if `remove_dir` or `remove_file` fail on any constituent paths, including the root path.
2312 /// As a result, the directory you are deleting must exist, meaning that this function is not idempotent.
2313 ///
2314 /// Consider ignoring the error if validating the removal is not required for your use case.
2315 ///
2316 /// [`fs::remove_file`]: remove_file
2317 /// [`fs::remove_dir`]: remove_dir
2318 ///
2319 /// # Examples
2320 ///
2321 /// ```no_run
2322 /// use std::fs;
2323 ///
2324 /// fn main() -> std::io::Result<()> {
2325 ///     fs::remove_dir_all("/some/dir")?;
2326 ///     Ok(())
2327 /// }
2328 /// ```
2329 #[stable(feature = "rust1", since = "1.0.0")]
remove_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()>2330 pub fn remove_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
2331     fs_imp::remove_dir_all(path.as_ref())
2332 }
2333 
2334 /// Returns an iterator over the entries within a directory.
2335 ///
2336 /// The iterator will yield instances of <code>[io::Result]<[DirEntry]></code>.
2337 /// New errors may be encountered after an iterator is initially constructed.
2338 /// Entries for the current and parent directories (typically `.` and `..`) are
2339 /// skipped.
2340 ///
2341 /// # Platform-specific behavior
2342 ///
2343 /// This function currently corresponds to the `opendir` function on Unix
2344 /// and the `FindFirstFile` function on Windows. Advancing the iterator
2345 /// currently corresponds to `readdir` on Unix and `FindNextFile` on Windows.
2346 /// Note that, this [may change in the future][changes].
2347 ///
2348 /// [changes]: io#platform-specific-behavior
2349 ///
2350 /// The order in which this iterator returns entries is platform and filesystem
2351 /// dependent.
2352 ///
2353 /// # Errors
2354 ///
2355 /// This function will return an error in the following situations, but is not
2356 /// limited to just these cases:
2357 ///
2358 /// * The provided `path` doesn't exist.
2359 /// * The process lacks permissions to view the contents.
2360 /// * The `path` points at a non-directory file.
2361 ///
2362 /// # Examples
2363 ///
2364 /// ```
2365 /// use std::io;
2366 /// use std::fs::{self, DirEntry};
2367 /// use std::path::Path;
2368 ///
2369 /// // one possible implementation of walking a directory only visiting files
2370 /// fn visit_dirs(dir: &Path, cb: &dyn Fn(&DirEntry)) -> io::Result<()> {
2371 ///     if dir.is_dir() {
2372 ///         for entry in fs::read_dir(dir)? {
2373 ///             let entry = entry?;
2374 ///             let path = entry.path();
2375 ///             if path.is_dir() {
2376 ///                 visit_dirs(&path, cb)?;
2377 ///             } else {
2378 ///                 cb(&entry);
2379 ///             }
2380 ///         }
2381 ///     }
2382 ///     Ok(())
2383 /// }
2384 /// ```
2385 ///
2386 /// ```rust,no_run
2387 /// use std::{fs, io};
2388 ///
2389 /// fn main() -> io::Result<()> {
2390 ///     let mut entries = fs::read_dir(".")?
2391 ///         .map(|res| res.map(|e| e.path()))
2392 ///         .collect::<Result<Vec<_>, io::Error>>()?;
2393 ///
2394 ///     // The order in which `read_dir` returns entries is not guaranteed. If reproducible
2395 ///     // ordering is required the entries should be explicitly sorted.
2396 ///
2397 ///     entries.sort();
2398 ///
2399 ///     // The entries have now been sorted by their path.
2400 ///
2401 ///     Ok(())
2402 /// }
2403 /// ```
2404 #[stable(feature = "rust1", since = "1.0.0")]
read_dir<P: AsRef<Path>>(path: P) -> io::Result<ReadDir>2405 pub fn read_dir<P: AsRef<Path>>(path: P) -> io::Result<ReadDir> {
2406     fs_imp::readdir(path.as_ref()).map(ReadDir)
2407 }
2408 
2409 /// Changes the permissions found on a file or a directory.
2410 ///
2411 /// # Platform-specific behavior
2412 ///
2413 /// This function currently corresponds to the `chmod` function on Unix
2414 /// and the `SetFileAttributes` function on Windows.
2415 /// Note that, this [may change in the future][changes].
2416 ///
2417 /// [changes]: io#platform-specific-behavior
2418 ///
2419 /// # Errors
2420 ///
2421 /// This function will return an error in the following situations, but is not
2422 /// limited to just these cases:
2423 ///
2424 /// * `path` does not exist.
2425 /// * The user lacks the permission to change attributes of the file.
2426 ///
2427 /// # Examples
2428 ///
2429 /// ```no_run
2430 /// use std::fs;
2431 ///
2432 /// fn main() -> std::io::Result<()> {
2433 ///     let mut perms = fs::metadata("foo.txt")?.permissions();
2434 ///     perms.set_readonly(true);
2435 ///     fs::set_permissions("foo.txt", perms)?;
2436 ///     Ok(())
2437 /// }
2438 /// ```
2439 #[stable(feature = "set_permissions", since = "1.1.0")]
set_permissions<P: AsRef<Path>>(path: P, perm: Permissions) -> io::Result<()>2440 pub fn set_permissions<P: AsRef<Path>>(path: P, perm: Permissions) -> io::Result<()> {
2441     fs_imp::set_perm(path.as_ref(), perm.0)
2442 }
2443 
2444 impl DirBuilder {
2445     /// Creates a new set of options with default mode/security settings for all
2446     /// platforms and also non-recursive.
2447     ///
2448     /// # Examples
2449     ///
2450     /// ```
2451     /// use std::fs::DirBuilder;
2452     ///
2453     /// let builder = DirBuilder::new();
2454     /// ```
2455     #[stable(feature = "dir_builder", since = "1.6.0")]
2456     #[must_use]
new() -> DirBuilder2457     pub fn new() -> DirBuilder {
2458         DirBuilder { inner: fs_imp::DirBuilder::new(), recursive: false }
2459     }
2460 
2461     /// Indicates that directories should be created recursively, creating all
2462     /// parent directories. Parents that do not exist are created with the same
2463     /// security and permissions settings.
2464     ///
2465     /// This option defaults to `false`.
2466     ///
2467     /// # Examples
2468     ///
2469     /// ```
2470     /// use std::fs::DirBuilder;
2471     ///
2472     /// let mut builder = DirBuilder::new();
2473     /// builder.recursive(true);
2474     /// ```
2475     #[stable(feature = "dir_builder", since = "1.6.0")]
recursive(&mut self, recursive: bool) -> &mut Self2476     pub fn recursive(&mut self, recursive: bool) -> &mut Self {
2477         self.recursive = recursive;
2478         self
2479     }
2480 
2481     /// Creates the specified directory with the options configured in this
2482     /// builder.
2483     ///
2484     /// It is considered an error if the directory already exists unless
2485     /// recursive mode is enabled.
2486     ///
2487     /// # Examples
2488     ///
2489     /// ```no_run
2490     /// use std::fs::{self, DirBuilder};
2491     ///
2492     /// let path = "/tmp/foo/bar/baz";
2493     /// DirBuilder::new()
2494     ///     .recursive(true)
2495     ///     .create(path).unwrap();
2496     ///
2497     /// assert!(fs::metadata(path).unwrap().is_dir());
2498     /// ```
2499     #[stable(feature = "dir_builder", since = "1.6.0")]
create<P: AsRef<Path>>(&self, path: P) -> io::Result<()>2500     pub fn create<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
2501         self._create(path.as_ref())
2502     }
2503 
_create(&self, path: &Path) -> io::Result<()>2504     fn _create(&self, path: &Path) -> io::Result<()> {
2505         if self.recursive { self.create_dir_all(path) } else { self.inner.mkdir(path) }
2506     }
2507 
create_dir_all(&self, path: &Path) -> io::Result<()>2508     fn create_dir_all(&self, path: &Path) -> io::Result<()> {
2509         if path == Path::new("") {
2510             return Ok(());
2511         }
2512 
2513         match self.inner.mkdir(path) {
2514             Ok(()) => return Ok(()),
2515             Err(ref e) if e.kind() == io::ErrorKind::NotFound => {}
2516             Err(_) if path.is_dir() => return Ok(()),
2517             Err(e) => return Err(e),
2518         }
2519         match path.parent() {
2520             Some(p) => self.create_dir_all(p)?,
2521             None => {
2522                 return Err(io::const_io_error!(
2523                     io::ErrorKind::Uncategorized,
2524                     "failed to create whole tree",
2525                 ));
2526             }
2527         }
2528         match self.inner.mkdir(path) {
2529             Ok(()) => Ok(()),
2530             Err(_) if path.is_dir() => Ok(()),
2531             Err(e) => Err(e),
2532         }
2533     }
2534 }
2535 
2536 impl AsInnerMut<fs_imp::DirBuilder> for DirBuilder {
2537     #[inline]
as_inner_mut(&mut self) -> &mut fs_imp::DirBuilder2538     fn as_inner_mut(&mut self) -> &mut fs_imp::DirBuilder {
2539         &mut self.inner
2540     }
2541 }
2542 
2543 /// Returns `Ok(true)` if the path points at an existing entity.
2544 ///
2545 /// This function will traverse symbolic links to query information about the
2546 /// destination file. In case of broken symbolic links this will return `Ok(false)`.
2547 ///
2548 /// As opposed to the [`Path::exists`] method, this will only return `Ok(true)` or `Ok(false)`
2549 /// if the path was _verified_ to exist or not exist. If its existence can neither be confirmed
2550 /// nor denied, an `Err(_)` will be propagated instead. This can be the case if e.g. listing
2551 /// permission is denied on one of the parent directories.
2552 ///
2553 /// Note that while this avoids some pitfalls of the `exists()` method, it still can not
2554 /// prevent time-of-check to time-of-use (TOCTOU) bugs. You should only use it in scenarios
2555 /// where those bugs are not an issue.
2556 ///
2557 /// # Examples
2558 ///
2559 /// ```no_run
2560 /// #![feature(fs_try_exists)]
2561 /// use std::fs;
2562 ///
2563 /// assert!(!fs::try_exists("does_not_exist.txt").expect("Can't check existence of file does_not_exist.txt"));
2564 /// assert!(fs::try_exists("/root/secret_file.txt").is_err());
2565 /// ```
2566 ///
2567 /// [`Path::exists`]: crate::path::Path::exists
2568 // FIXME: stabilization should modify documentation of `exists()` to recommend this method
2569 // instead.
2570 #[unstable(feature = "fs_try_exists", issue = "83186")]
2571 #[inline]
try_exists<P: AsRef<Path>>(path: P) -> io::Result<bool>2572 pub fn try_exists<P: AsRef<Path>>(path: P) -> io::Result<bool> {
2573     fs_imp::try_exists(path.as_ref())
2574 }
2575