]> git.lizzy.rs Git - rust.git/blob - library/std/src/fs.rs
Rollup merge of #79399 - pickfire:patch-3, r=JohnTitor
[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 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 #[doc(alias = "delete")]
1528 #[stable(feature = "rust1", since = "1.0.0")]
1529 pub fn remove_file<P: AsRef<Path>>(path: P) -> io::Result<()> {
1530     fs_imp::unlink(path.as_ref())
1531 }
1532
1533 /// Given a path, query the file system to get information about a file,
1534 /// directory, etc.
1535 ///
1536 /// This function will traverse symbolic links to query information about the
1537 /// destination file.
1538 ///
1539 /// # Platform-specific behavior
1540 ///
1541 /// This function currently corresponds to the `stat` function on Unix
1542 /// and the `GetFileAttributesEx` function on Windows.
1543 /// Note that, this [may change in the future][changes].
1544 ///
1545 /// [changes]: io#platform-specific-behavior
1546 ///
1547 /// # Errors
1548 ///
1549 /// This function will return an error in the following situations, but is not
1550 /// limited to just these cases:
1551 ///
1552 /// * The user lacks permissions to perform `metadata` call on `path`.
1553 /// * `path` does not exist.
1554 ///
1555 /// # Examples
1556 ///
1557 /// ```rust,no_run
1558 /// use std::fs;
1559 ///
1560 /// fn main() -> std::io::Result<()> {
1561 ///     let attr = fs::metadata("/some/file/path.txt")?;
1562 ///     // inspect attr ...
1563 ///     Ok(())
1564 /// }
1565 /// ```
1566 #[stable(feature = "rust1", since = "1.0.0")]
1567 pub fn metadata<P: AsRef<Path>>(path: P) -> io::Result<Metadata> {
1568     fs_imp::stat(path.as_ref()).map(Metadata)
1569 }
1570
1571 /// Query the metadata about a file without following symlinks.
1572 ///
1573 /// # Platform-specific behavior
1574 ///
1575 /// This function currently corresponds to the `lstat` 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::symlink_metadata("/some/file/path.txt")?;
1596 ///     // inspect attr ...
1597 ///     Ok(())
1598 /// }
1599 /// ```
1600 #[stable(feature = "symlink_metadata", since = "1.1.0")]
1601 pub fn symlink_metadata<P: AsRef<Path>>(path: P) -> io::Result<Metadata> {
1602     fs_imp::lstat(path.as_ref()).map(Metadata)
1603 }
1604
1605 /// Rename a file or directory to a new name, replacing the original file if
1606 /// `to` already exists.
1607 ///
1608 /// This will not work if the new name is on a different mount point.
1609 ///
1610 /// # Platform-specific behavior
1611 ///
1612 /// This function currently corresponds to the `rename` function on Unix
1613 /// and the `MoveFileEx` function with the `MOVEFILE_REPLACE_EXISTING` flag on Windows.
1614 ///
1615 /// Because of this, the behavior when both `from` and `to` exist differs. On
1616 /// Unix, if `from` is a directory, `to` must also be an (empty) directory. If
1617 /// `from` is not a directory, `to` must also be not a directory. In contrast,
1618 /// on Windows, `from` can be anything, but `to` must *not* be a directory.
1619 ///
1620 /// Note that, this [may change in the future][changes].
1621 ///
1622 /// [changes]: io#platform-specific-behavior
1623 ///
1624 /// # Errors
1625 ///
1626 /// This function will return an error in the following situations, but is not
1627 /// limited to just these cases:
1628 ///
1629 /// * `from` does not exist.
1630 /// * The user lacks permissions to view contents.
1631 /// * `from` and `to` are on separate filesystems.
1632 ///
1633 /// # Examples
1634 ///
1635 /// ```no_run
1636 /// use std::fs;
1637 ///
1638 /// fn main() -> std::io::Result<()> {
1639 ///     fs::rename("a.txt", "b.txt")?; // Rename a.txt to b.txt
1640 ///     Ok(())
1641 /// }
1642 /// ```
1643 #[stable(feature = "rust1", since = "1.0.0")]
1644 pub fn rename<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()> {
1645     fs_imp::rename(from.as_ref(), to.as_ref())
1646 }
1647
1648 /// Copies the contents of one file to another. This function will also
1649 /// copy the permission bits of the original file to the destination file.
1650 ///
1651 /// This function will **overwrite** the contents of `to`.
1652 ///
1653 /// Note that if `from` and `to` both point to the same file, then the file
1654 /// will likely get truncated by this operation.
1655 ///
1656 /// On success, the total number of bytes copied is returned and it is equal to
1657 /// the length of the `to` file as reported by `metadata`.
1658 ///
1659 /// If you’re wanting to copy the contents of one file to another and you’re
1660 /// working with [`File`]s, see the [`io::copy()`] function.
1661 ///
1662 /// # Platform-specific behavior
1663 ///
1664 /// This function currently corresponds to the `open` function in Unix
1665 /// with `O_RDONLY` for `from` and `O_WRONLY`, `O_CREAT`, and `O_TRUNC` for `to`.
1666 /// `O_CLOEXEC` is set for returned file descriptors.
1667 /// On Windows, this function currently corresponds to `CopyFileEx`. Alternate
1668 /// NTFS streams are copied but only the size of the main stream is returned by
1669 /// this function. On MacOS, this function corresponds to `fclonefileat` and
1670 /// `fcopyfile`.
1671 /// Note that, this [may change in the future][changes].
1672 ///
1673 /// [changes]: io#platform-specific-behavior
1674 ///
1675 /// # Errors
1676 ///
1677 /// This function will return an error in the following situations, but is not
1678 /// limited to just these cases:
1679 ///
1680 /// * `from` is neither a regular file nor a symlink to a regular file.
1681 /// * `from` does not exist.
1682 /// * The current process does not have the permission rights to read
1683 ///   `from` or write `to`.
1684 ///
1685 /// # Examples
1686 ///
1687 /// ```no_run
1688 /// use std::fs;
1689 ///
1690 /// fn main() -> std::io::Result<()> {
1691 ///     fs::copy("foo.txt", "bar.txt")?;  // Copy foo.txt to bar.txt
1692 ///     Ok(())
1693 /// }
1694 /// ```
1695 #[stable(feature = "rust1", since = "1.0.0")]
1696 pub fn copy<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<u64> {
1697     fs_imp::copy(from.as_ref(), to.as_ref())
1698 }
1699
1700 /// Creates a new hard link on the filesystem.
1701 ///
1702 /// The `link` path will be a link pointing to the `original` path. Note that
1703 /// systems often require these two paths to both be located on the same
1704 /// filesystem.
1705 ///
1706 /// If `original` names a symbolic link, it is platform-specific whether the
1707 /// symbolic link is followed. On platforms where it's possible to not follow
1708 /// it, it is not followed, and the created hard link points to the symbolic
1709 /// link itself.
1710 ///
1711 /// # Platform-specific behavior
1712 ///
1713 /// This function currently corresponds to the `linkat` function with no flags
1714 /// on Unix and the `CreateHardLink` function on Windows.
1715 /// Note that, this [may change in the future][changes].
1716 ///
1717 /// [changes]: io#platform-specific-behavior
1718 ///
1719 /// # Errors
1720 ///
1721 /// This function will return an error in the following situations, but is not
1722 /// limited to just these cases:
1723 ///
1724 /// * The `original` path is not a file or doesn't exist.
1725 ///
1726 /// # Examples
1727 ///
1728 /// ```no_run
1729 /// use std::fs;
1730 ///
1731 /// fn main() -> std::io::Result<()> {
1732 ///     fs::hard_link("a.txt", "b.txt")?; // Hard link a.txt to b.txt
1733 ///     Ok(())
1734 /// }
1735 /// ```
1736 #[stable(feature = "rust1", since = "1.0.0")]
1737 pub fn hard_link<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) -> io::Result<()> {
1738     fs_imp::link(original.as_ref(), link.as_ref())
1739 }
1740
1741 /// Creates a new symbolic link on the filesystem.
1742 ///
1743 /// The `link` path will be a symbolic link pointing to the `original` path.
1744 /// On Windows, this will be a file symlink, not a directory symlink;
1745 /// for this reason, the platform-specific [`std::os::unix::fs::symlink`]
1746 /// and [`std::os::windows::fs::symlink_file`] or [`symlink_dir`] should be
1747 /// used instead to make the intent explicit.
1748 ///
1749 /// [`std::os::unix::fs::symlink`]: crate::os::unix::fs::symlink
1750 /// [`std::os::windows::fs::symlink_file`]: crate::os::windows::fs::symlink_file
1751 /// [`symlink_dir`]: crate::os::windows::fs::symlink_dir
1752 ///
1753 /// # Examples
1754 ///
1755 /// ```no_run
1756 /// use std::fs;
1757 ///
1758 /// fn main() -> std::io::Result<()> {
1759 ///     fs::soft_link("a.txt", "b.txt")?;
1760 ///     Ok(())
1761 /// }
1762 /// ```
1763 #[stable(feature = "rust1", since = "1.0.0")]
1764 #[rustc_deprecated(
1765     since = "1.1.0",
1766     reason = "replaced with std::os::unix::fs::symlink and \
1767               std::os::windows::fs::{symlink_file, symlink_dir}"
1768 )]
1769 pub fn soft_link<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) -> io::Result<()> {
1770     fs_imp::symlink(original.as_ref(), link.as_ref())
1771 }
1772
1773 /// Reads a symbolic link, returning the file that the link points to.
1774 ///
1775 /// # Platform-specific behavior
1776 ///
1777 /// This function currently corresponds to the `readlink` function on Unix
1778 /// and the `CreateFile` function with `FILE_FLAG_OPEN_REPARSE_POINT` and
1779 /// `FILE_FLAG_BACKUP_SEMANTICS` flags on Windows.
1780 /// Note that, this [may change in the future][changes].
1781 ///
1782 /// [changes]: io#platform-specific-behavior
1783 ///
1784 /// # Errors
1785 ///
1786 /// This function will return an error in the following situations, but is not
1787 /// limited to just these cases:
1788 ///
1789 /// * `path` is not a symbolic link.
1790 /// * `path` does not exist.
1791 ///
1792 /// # Examples
1793 ///
1794 /// ```no_run
1795 /// use std::fs;
1796 ///
1797 /// fn main() -> std::io::Result<()> {
1798 ///     let path = fs::read_link("a.txt")?;
1799 ///     Ok(())
1800 /// }
1801 /// ```
1802 #[stable(feature = "rust1", since = "1.0.0")]
1803 pub fn read_link<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
1804     fs_imp::readlink(path.as_ref())
1805 }
1806
1807 /// Returns the canonical, absolute form of a path with all intermediate
1808 /// components normalized and symbolic links resolved.
1809 ///
1810 /// # Platform-specific behavior
1811 ///
1812 /// This function currently corresponds to the `realpath` function on Unix
1813 /// and the `CreateFile` and `GetFinalPathNameByHandle` functions on Windows.
1814 /// Note that, this [may change in the future][changes].
1815 ///
1816 /// On Windows, this converts the path to use [extended length path][path]
1817 /// syntax, which allows your program to use longer path names, but means you
1818 /// can only join backslash-delimited paths to it, and it may be incompatible
1819 /// with other applications (if passed to the application on the command-line,
1820 /// or written to a file another application may read).
1821 ///
1822 /// [changes]: io#platform-specific-behavior
1823 /// [path]: https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file
1824 ///
1825 /// # Errors
1826 ///
1827 /// This function will return an error in the following situations, but is not
1828 /// limited to just these cases:
1829 ///
1830 /// * `path` does not exist.
1831 /// * A non-final component in path is not a directory.
1832 ///
1833 /// # Examples
1834 ///
1835 /// ```no_run
1836 /// use std::fs;
1837 ///
1838 /// fn main() -> std::io::Result<()> {
1839 ///     let path = fs::canonicalize("../a/../foo.txt")?;
1840 ///     Ok(())
1841 /// }
1842 /// ```
1843 #[stable(feature = "fs_canonicalize", since = "1.5.0")]
1844 pub fn canonicalize<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
1845     fs_imp::canonicalize(path.as_ref())
1846 }
1847
1848 /// Creates a new, empty directory at the provided path
1849 ///
1850 /// # Platform-specific behavior
1851 ///
1852 /// This function currently corresponds to the `mkdir` function on Unix
1853 /// and the `CreateDirectory` function on Windows.
1854 /// Note that, this [may change in the future][changes].
1855 ///
1856 /// [changes]: io#platform-specific-behavior
1857 ///
1858 /// **NOTE**: If a parent of the given path doesn't exist, this function will
1859 /// return an error. To create a directory and all its missing parents at the
1860 /// same time, use the [`create_dir_all`] function.
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 /// * User lacks permissions to create directory at `path`.
1868 /// * A parent of the given path doesn't exist. (To create a directory and all
1869 ///   its missing parents at the same time, use the [`create_dir_all`]
1870 ///   function.)
1871 /// * `path` already exists.
1872 ///
1873 /// # Examples
1874 ///
1875 /// ```no_run
1876 /// use std::fs;
1877 ///
1878 /// fn main() -> std::io::Result<()> {
1879 ///     fs::create_dir("/some/dir")?;
1880 ///     Ok(())
1881 /// }
1882 /// ```
1883 #[stable(feature = "rust1", since = "1.0.0")]
1884 pub fn create_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
1885     DirBuilder::new().create(path.as_ref())
1886 }
1887
1888 /// Recursively create a directory and all of its parent components if they
1889 /// are missing.
1890 ///
1891 /// # Platform-specific behavior
1892 ///
1893 /// This function currently corresponds to the `mkdir` function on Unix
1894 /// and the `CreateDirectory` function on Windows.
1895 /// Note that, this [may change in the future][changes].
1896 ///
1897 /// [changes]: io#platform-specific-behavior
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 /// * If any directory in the path specified by `path`
1905 /// does not already exist and it could not be created otherwise. The specific
1906 /// error conditions for when a directory is being created (after it is
1907 /// determined to not exist) are outlined by [`fs::create_dir`].
1908 ///
1909 /// Notable exception is made for situations where any of the directories
1910 /// specified in the `path` could not be created as it was being created concurrently.
1911 /// Such cases are considered to be successful. That is, calling `create_dir_all`
1912 /// concurrently from multiple threads or processes is guaranteed not to fail
1913 /// due to a race condition with itself.
1914 ///
1915 /// [`fs::create_dir`]: create_dir
1916 ///
1917 /// # Examples
1918 ///
1919 /// ```no_run
1920 /// use std::fs;
1921 ///
1922 /// fn main() -> std::io::Result<()> {
1923 ///     fs::create_dir_all("/some/dir")?;
1924 ///     Ok(())
1925 /// }
1926 /// ```
1927 #[stable(feature = "rust1", since = "1.0.0")]
1928 pub fn create_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
1929     DirBuilder::new().recursive(true).create(path.as_ref())
1930 }
1931
1932 /// Removes an empty directory.
1933 ///
1934 /// # Platform-specific behavior
1935 ///
1936 /// This function currently corresponds to the `rmdir` function on Unix
1937 /// and the `RemoveDirectory` function on Windows.
1938 /// Note that, this [may change in the future][changes].
1939 ///
1940 /// [changes]: io#platform-specific-behavior
1941 ///
1942 /// # Errors
1943 ///
1944 /// This function will return an error in the following situations, but is not
1945 /// limited to just these cases:
1946 ///
1947 /// * `path` doesn't exist.
1948 /// * `path` isn't a directory.
1949 /// * The user lacks permissions to remove the directory at the provided `path`.
1950 /// * The directory isn't empty.
1951 ///
1952 /// # Examples
1953 ///
1954 /// ```no_run
1955 /// use std::fs;
1956 ///
1957 /// fn main() -> std::io::Result<()> {
1958 ///     fs::remove_dir("/some/dir")?;
1959 ///     Ok(())
1960 /// }
1961 /// ```
1962 #[doc(alias = "delete")]
1963 #[stable(feature = "rust1", since = "1.0.0")]
1964 pub fn remove_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
1965     fs_imp::rmdir(path.as_ref())
1966 }
1967
1968 /// Removes a directory at this path, after removing all its contents. Use
1969 /// carefully!
1970 ///
1971 /// This function does **not** follow symbolic links and it will simply remove the
1972 /// symbolic link itself.
1973 ///
1974 /// # Platform-specific behavior
1975 ///
1976 /// This function currently corresponds to `opendir`, `lstat`, `rm` and `rmdir` functions on Unix
1977 /// and the `FindFirstFile`, `GetFileAttributesEx`, `DeleteFile`, and `RemoveDirectory` functions
1978 /// on Windows.
1979 /// Note that, this [may change in the future][changes].
1980 ///
1981 /// [changes]: io#platform-specific-behavior
1982 ///
1983 /// # Errors
1984 ///
1985 /// See [`fs::remove_file`] and [`fs::remove_dir`].
1986 ///
1987 /// [`fs::remove_file`]: remove_file
1988 /// [`fs::remove_dir`]: remove_dir
1989 ///
1990 /// # Examples
1991 ///
1992 /// ```no_run
1993 /// use std::fs;
1994 ///
1995 /// fn main() -> std::io::Result<()> {
1996 ///     fs::remove_dir_all("/some/dir")?;
1997 ///     Ok(())
1998 /// }
1999 /// ```
2000 #[doc(alias = "delete")]
2001 #[stable(feature = "rust1", since = "1.0.0")]
2002 pub fn remove_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
2003     fs_imp::remove_dir_all(path.as_ref())
2004 }
2005
2006 /// Returns an iterator over the entries within a directory.
2007 ///
2008 /// The iterator will yield instances of [`io::Result`]`<`[`DirEntry`]`>`.
2009 /// New errors may be encountered after an iterator is initially constructed.
2010 ///
2011 /// # Platform-specific behavior
2012 ///
2013 /// This function currently corresponds to the `opendir` function on Unix
2014 /// and the `FindFirstFile` function on Windows. Advancing the iterator
2015 /// currently corresponds to `readdir` on Unix and `FindNextFile` on Windows.
2016 /// Note that, this [may change in the future][changes].
2017 ///
2018 /// [changes]: io#platform-specific-behavior
2019 ///
2020 /// The order in which this iterator returns entries is platform and filesystem
2021 /// dependent.
2022 ///
2023 /// # Errors
2024 ///
2025 /// This function will return an error in the following situations, but is not
2026 /// limited to just these cases:
2027 ///
2028 /// * The provided `path` doesn't exist.
2029 /// * The process lacks permissions to view the contents.
2030 /// * The `path` points at a non-directory file.
2031 ///
2032 /// # Examples
2033 ///
2034 /// ```
2035 /// use std::io;
2036 /// use std::fs::{self, DirEntry};
2037 /// use std::path::Path;
2038 ///
2039 /// // one possible implementation of walking a directory only visiting files
2040 /// fn visit_dirs(dir: &Path, cb: &dyn Fn(&DirEntry)) -> io::Result<()> {
2041 ///     if dir.is_dir() {
2042 ///         for entry in fs::read_dir(dir)? {
2043 ///             let entry = entry?;
2044 ///             let path = entry.path();
2045 ///             if path.is_dir() {
2046 ///                 visit_dirs(&path, cb)?;
2047 ///             } else {
2048 ///                 cb(&entry);
2049 ///             }
2050 ///         }
2051 ///     }
2052 ///     Ok(())
2053 /// }
2054 /// ```
2055 ///
2056 /// ```rust,no_run
2057 /// use std::{fs, io};
2058 ///
2059 /// fn main() -> io::Result<()> {
2060 ///     let mut entries = fs::read_dir(".")?
2061 ///         .map(|res| res.map(|e| e.path()))
2062 ///         .collect::<Result<Vec<_>, io::Error>>()?;
2063 ///
2064 ///     // The order in which `read_dir` returns entries is not guaranteed. If reproducible
2065 ///     // ordering is required the entries should be explicitly sorted.
2066 ///
2067 ///     entries.sort();
2068 ///
2069 ///     // The entries have now been sorted by their path.
2070 ///
2071 ///     Ok(())
2072 /// }
2073 /// ```
2074 #[stable(feature = "rust1", since = "1.0.0")]
2075 pub fn read_dir<P: AsRef<Path>>(path: P) -> io::Result<ReadDir> {
2076     fs_imp::readdir(path.as_ref()).map(ReadDir)
2077 }
2078
2079 /// Changes the permissions found on a file or a directory.
2080 ///
2081 /// # Platform-specific behavior
2082 ///
2083 /// This function currently corresponds to the `chmod` function on Unix
2084 /// and the `SetFileAttributes` function on Windows.
2085 /// Note that, this [may change in the future][changes].
2086 ///
2087 /// [changes]: io#platform-specific-behavior
2088 ///
2089 /// # Errors
2090 ///
2091 /// This function will return an error in the following situations, but is not
2092 /// limited to just these cases:
2093 ///
2094 /// * `path` does not exist.
2095 /// * The user lacks the permission to change attributes of the file.
2096 ///
2097 /// # Examples
2098 ///
2099 /// ```no_run
2100 /// use std::fs;
2101 ///
2102 /// fn main() -> std::io::Result<()> {
2103 ///     let mut perms = fs::metadata("foo.txt")?.permissions();
2104 ///     perms.set_readonly(true);
2105 ///     fs::set_permissions("foo.txt", perms)?;
2106 ///     Ok(())
2107 /// }
2108 /// ```
2109 #[stable(feature = "set_permissions", since = "1.1.0")]
2110 pub fn set_permissions<P: AsRef<Path>>(path: P, perm: Permissions) -> io::Result<()> {
2111     fs_imp::set_perm(path.as_ref(), perm.0)
2112 }
2113
2114 impl DirBuilder {
2115     /// Creates a new set of options with default mode/security settings for all
2116     /// platforms and also non-recursive.
2117     ///
2118     /// # Examples
2119     ///
2120     /// ```
2121     /// use std::fs::DirBuilder;
2122     ///
2123     /// let builder = DirBuilder::new();
2124     /// ```
2125     #[stable(feature = "dir_builder", since = "1.6.0")]
2126     pub fn new() -> DirBuilder {
2127         DirBuilder { inner: fs_imp::DirBuilder::new(), recursive: false }
2128     }
2129
2130     /// Indicates that directories should be created recursively, creating all
2131     /// parent directories. Parents that do not exist are created with the same
2132     /// security and permissions settings.
2133     ///
2134     /// This option defaults to `false`.
2135     ///
2136     /// # Examples
2137     ///
2138     /// ```
2139     /// use std::fs::DirBuilder;
2140     ///
2141     /// let mut builder = DirBuilder::new();
2142     /// builder.recursive(true);
2143     /// ```
2144     #[stable(feature = "dir_builder", since = "1.6.0")]
2145     pub fn recursive(&mut self, recursive: bool) -> &mut Self {
2146         self.recursive = recursive;
2147         self
2148     }
2149
2150     /// Creates the specified directory with the options configured in this
2151     /// builder.
2152     ///
2153     /// It is considered an error if the directory already exists unless
2154     /// recursive mode is enabled.
2155     ///
2156     /// # Examples
2157     ///
2158     /// ```no_run
2159     /// use std::fs::{self, DirBuilder};
2160     ///
2161     /// let path = "/tmp/foo/bar/baz";
2162     /// DirBuilder::new()
2163     ///     .recursive(true)
2164     ///     .create(path).unwrap();
2165     ///
2166     /// assert!(fs::metadata(path).unwrap().is_dir());
2167     /// ```
2168     #[stable(feature = "dir_builder", since = "1.6.0")]
2169     pub fn create<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
2170         self._create(path.as_ref())
2171     }
2172
2173     fn _create(&self, path: &Path) -> io::Result<()> {
2174         if self.recursive { self.create_dir_all(path) } else { self.inner.mkdir(path) }
2175     }
2176
2177     fn create_dir_all(&self, path: &Path) -> io::Result<()> {
2178         if path == Path::new("") {
2179             return Ok(());
2180         }
2181
2182         match self.inner.mkdir(path) {
2183             Ok(()) => return Ok(()),
2184             Err(ref e) if e.kind() == io::ErrorKind::NotFound => {}
2185             Err(_) if path.is_dir() => return Ok(()),
2186             Err(e) => return Err(e),
2187         }
2188         match path.parent() {
2189             Some(p) => self.create_dir_all(p)?,
2190             None => {
2191                 return Err(io::Error::new_const(
2192                     io::ErrorKind::Other,
2193                     &"failed to create whole tree",
2194                 ));
2195             }
2196         }
2197         match self.inner.mkdir(path) {
2198             Ok(()) => Ok(()),
2199             Err(_) if path.is_dir() => Ok(()),
2200             Err(e) => Err(e),
2201         }
2202     }
2203 }
2204
2205 impl AsInnerMut<fs_imp::DirBuilder> for DirBuilder {
2206     fn as_inner_mut(&mut self) -> &mut fs_imp::DirBuilder {
2207         &mut self.inner
2208     }
2209 }