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