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