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