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