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