1 //! Filesystem manipulation operations.
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`.
8 #![stable(feature = "rust1", since = "1.0.0")]
9 #![deny(unsafe_op_in_unsafe_fn)]
11 #[cfg(all(test, not(any(target_os = "emscripten", target_env = "sgx"))))]
14 use crate::ffi
::OsString
;
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
;
22 /// A reference to an open file on the filesystem.
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.
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.
34 /// Creates a new file and write bytes to it (you can also use [`write()`]):
37 /// use std::fs::File;
38 /// use std::io::prelude::*;
40 /// fn main() -> std::io::Result<()> {
41 /// let mut file = File::create("foo.txt")?;
42 /// file.write_all(b"Hello, world!")?;
47 /// Read the contents of a file into a [`String`] (you can also use [`read`]):
50 /// use std::fs::File;
51 /// use std::io::prelude::*;
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!");
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>`]:
66 /// use std::fs::File;
67 /// use std::io::BufReader;
68 /// use std::io::prelude::*;
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!");
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.
88 /// # Platform-specific behavior
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`).
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")]
102 /// Metadata information about a file.
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
108 #[stable(feature = "rust1", since = "1.0.0")]
110 pub struct Metadata(fs_imp
::FileAttr
);
112 /// Iterator over the entries in a directory.
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
119 /// The order in which this iterator returns entries is platform and filesystem
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")]
128 pub struct ReadDir(fs_imp
::ReadDir
);
130 /// Entries returned by the [`ReadDir`] iterator.
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.
136 /// # Platform-specific behavior
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.
142 /// Note that this [may change in the future][changes].
144 /// [changes]: io#platform-specific-behavior
145 #[stable(feature = "rust1", since = "1.0.0")]
146 pub struct DirEntry(fs_imp
::DirEntry
);
148 /// Options and flags which can be used to configure how a file is opened.
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
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.
163 /// Opening a file to read:
166 /// use std::fs::OpenOptions;
168 /// let file = OpenOptions::new().read(true).open("foo.txt");
171 /// Opening a file for both reading and writing, as well as creating it if it
175 /// use std::fs::OpenOptions;
177 /// let file = OpenOptions::new()
181 /// .open("foo.txt");
183 #[derive(Clone, Debug)]
184 #[stable(feature = "rust1", since = "1.0.0")]
185 pub struct OpenOptions(fs_imp
::OpenOptions
);
187 /// Representation of the various permissions on a file.
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.
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
);
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
);
206 /// A builder used to create directories in various manners.
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")]
212 pub struct DirBuilder
{
213 inner
: fs_imp
::DirBuilder
,
217 /// Read the entire contents of a file into a bytes vector.
219 /// This is a convenience function for using [`File::open`] and [`read_to_end`]
220 /// with fewer imports and without an intermediate variable.
222 /// [`read_to_end`]: Read::read_to_end
226 /// This function will return an error if `path` does not already exist.
227 /// Other errors may also be returned according to [`OpenOptions::open`].
229 /// It will also return an error if it encounters while reading an error
230 /// of a kind other than [`io::ErrorKind::Interrupted`].
236 /// use std::net::SocketAddr;
238 /// fn main() -> Result<(), Box<dyn std::error::Error + 'static>> {
239 /// let foo: SocketAddr = String::from_utf8_lossy(&fs::read("address.txt")?).parse()?;
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
)?
;
254 /// Read the entire contents of a file into a string.
256 /// This is a convenience function for using [`File::open`] and [`read_to_string`]
257 /// with fewer imports and without an intermediate variable.
259 /// [`read_to_string`]: Read::read_to_string
263 /// This function will return an error if `path` does not already exist.
264 /// Other errors may also be returned according to [`OpenOptions::open`].
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.
274 /// use std::net::SocketAddr;
275 /// use std::error::Error;
277 /// fn main() -> Result<(), Box<dyn Error>> {
278 /// let foo: SocketAddr = fs::read_to_string("address.txt")?.parse()?;
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
)?
;
293 /// Write a slice as the entire contents of a file.
295 /// This function will create a file if it does not exist,
296 /// and will entirely replace its contents if it does.
298 /// This is a convenience function for using [`File::create`] and [`write_all`]
299 /// with fewer imports.
301 /// [`write_all`]: Write::write_all
308 /// fn main() -> std::io::Result<()> {
309 /// fs::write("foo.txt", b"Lorem ipsum")?;
310 /// fs::write("bar.txt", "dolor sit")?;
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
)
319 inner(path
.as_ref(), contents
.as_ref())
323 /// Attempts to open a file in read-only mode.
325 /// See the [`OpenOptions::open`] method for more details.
329 /// This function will return an error if `path` does not already exist.
330 /// Other errors may also be returned according to [`OpenOptions::open`].
335 /// use std::fs::File;
337 /// fn main() -> std::io::Result<()> {
338 /// let mut f = File::open("foo.txt")?;
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())
347 /// Opens a file in write-only mode.
349 /// This function will create a file if it does not exist,
350 /// and will truncate it if it does.
352 /// See the [`OpenOptions::open`] function for more details.
357 /// use std::fs::File;
359 /// fn main() -> std::io::Result<()> {
360 /// let mut f = File::create("foo.txt")?;
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())
369 /// Returns a new OpenOptions object.
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.
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`.
381 /// See the [`OpenOptions::new`] function for more details.
386 /// use std::fs::File;
388 /// fn main() -> std::io::Result<()> {
389 /// let mut f = File::options().append(true).open("example.log")?;
394 #[stable(feature = "with_options", since = "1.58.0")]
395 pub fn options() -> OpenOptions
{
399 /// Attempts to sync all OS-internal metadata to disk.
401 /// This function will attempt to ensure that all in-memory data reaches the
402 /// filesystem before returning.
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.
411 /// use std::fs::File;
412 /// use std::io::prelude::*;
414 /// fn main() -> std::io::Result<()> {
415 /// let mut f = File::create("foo.txt")?;
416 /// f.write_all(b"Hello, world!")?;
422 #[stable(feature = "rust1", since = "1.0.0")]
423 pub fn sync_all(&self) -> io
::Result
<()> {
427 /// This function is similar to [`sync_all`], except that it might not
428 /// synchronize file metadata to the filesystem.
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
434 /// Note that some platforms may simply implement this in terms of
437 /// [`sync_all`]: File::sync_all
442 /// use std::fs::File;
443 /// use std::io::prelude::*;
445 /// fn main() -> std::io::Result<()> {
446 /// let mut f = File::create("foo.txt")?;
447 /// f.write_all(b"Hello, world!")?;
453 #[stable(feature = "rust1", since = "1.0.0")]
454 pub fn sync_data(&self) -> io
::Result
<()> {
455 self.inner
.datasync()
458 /// Truncates or extends the underlying file, updating the size of
459 /// this file to become `size`.
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
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
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.
479 /// use std::fs::File;
481 /// fn main() -> std::io::Result<()> {
482 /// let mut f = File::create("foo.txt")?;
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
)
495 /// Queries metadata about the underlying file.
500 /// use std::fs::File;
502 /// fn main() -> std::io::Result<()> {
503 /// let mut f = File::open("foo.txt")?;
504 /// let metadata = f.metadata()?;
508 #[stable(feature = "rust1", since = "1.0.0")]
509 pub fn metadata(&self) -> io
::Result
<Metadata
> {
510 self.inner
.file_attr().map(Metadata
)
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.
519 /// Creates two handles for a file named `foo.txt`:
522 /// use std::fs::File;
524 /// fn main() -> std::io::Result<()> {
525 /// let mut file = File::open("foo.txt")?;
526 /// let file_copy = file.try_clone()?;
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
536 /// use std::fs::File;
537 /// use std::io::SeekFrom;
538 /// use std::io::prelude::*;
540 /// fn main() -> std::io::Result<()> {
541 /// let mut file = File::open("foo.txt")?;
542 /// let mut file_copy = file.try_clone()?;
544 /// file.seek(SeekFrom::Start(3))?;
546 /// let mut contents = vec![];
547 /// file_copy.read_to_end(&mut contents)?;
548 /// assert_eq!(contents, b"def\n");
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()? }
)
557 /// Changes the permissions on the underlying file.
559 /// # Platform-specific behavior
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].
565 /// [changes]: io#platform-specific-behavior
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.
576 /// fn main() -> std::io::Result<()> {
577 /// use std::fs::File;
579 /// let file = File::open("foo.txt")?;
580 /// let mut perms = file.metadata()?.permissions();
581 /// perms.set_readonly(true);
582 /// file.set_permissions(perms)?;
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)
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.
601 impl AsInner
<fs_imp
::File
> for File
{
602 fn as_inner(&self) -> &fs_imp
::File
{
606 impl FromInner
<fs_imp
::File
> for File
{
607 fn from_inner(f
: fs_imp
::File
) -> File
{
611 impl IntoInner
<fs_imp
::File
> for File
{
612 fn into_inner(self) -> fs_imp
::File
{
617 #[stable(feature = "rust1", since = "1.0.0")]
618 impl fmt
::Debug
for File
{
619 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
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
630 size
.saturating_sub(pos
) as usize
633 #[stable(feature = "rust1", since = "1.0.0")]
635 fn read(&mut self, buf
: &mut [u8]) -> io
::Result
<usize> {
639 fn read_vectored(&mut self, bufs
: &mut [IoSliceMut
<'_
>]) -> io
::Result
<usize> {
640 self.inner
.read_vectored(bufs
)
643 fn read_buf(&mut self, buf
: &mut ReadBuf
<'_
>) -> io
::Result
<()> {
644 self.inner
.read_buf(buf
)
648 fn is_read_vectored(&self) -> bool
{
649 self.inner
.is_read_vectored()
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
)
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
)
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
)
670 fn write_vectored(&mut self, bufs
: &[IoSlice
<'_
>]) -> io
::Result
<usize> {
671 self.inner
.write_vectored(bufs
)
675 fn is_write_vectored(&self) -> bool
{
676 self.inner
.is_write_vectored()
679 fn flush(&mut self) -> io
::Result
<()> {
683 #[stable(feature = "rust1", since = "1.0.0")]
685 fn seek(&mut self, pos
: SeekFrom
) -> io
::Result
<u64> {
689 #[stable(feature = "rust1", since = "1.0.0")]
690 impl Read
for &File
{
691 fn read(&mut self, buf
: &mut [u8]) -> io
::Result
<usize> {
695 fn read_buf(&mut self, buf
: &mut ReadBuf
<'_
>) -> io
::Result
<()> {
696 self.inner
.read_buf(buf
)
699 fn read_vectored(&mut self, bufs
: &mut [IoSliceMut
<'_
>]) -> io
::Result
<usize> {
700 self.inner
.read_vectored(bufs
)
704 fn is_read_vectored(&self) -> bool
{
705 self.inner
.is_read_vectored()
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
)
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
)
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
)
726 fn write_vectored(&mut self, bufs
: &[IoSlice
<'_
>]) -> io
::Result
<usize> {
727 self.inner
.write_vectored(bufs
)
731 fn is_write_vectored(&self) -> bool
{
732 self.inner
.is_write_vectored()
735 fn flush(&mut self) -> io
::Result
<()> {
739 #[stable(feature = "rust1", since = "1.0.0")]
740 impl Seek
for &File
{
741 fn seek(&mut self, pos
: SeekFrom
) -> io
::Result
<u64> {
747 /// Creates a blank new set of options ready for configuration.
749 /// All options are initially set to `false`.
754 /// use std::fs::OpenOptions;
756 /// let mut options = OpenOptions::new();
757 /// let file = options.read(true).open("foo.txt");
759 #[stable(feature = "rust1", since = "1.0.0")]
761 pub fn new() -> Self {
762 OpenOptions(fs_imp
::OpenOptions
::new())
765 /// Sets the option for read access.
767 /// This option, when true, will indicate that the file should be
768 /// `read`-able if opened.
773 /// use std::fs::OpenOptions;
775 /// let file = OpenOptions::new().read(true).open("foo.txt");
777 #[stable(feature = "rust1", since = "1.0.0")]
778 pub fn read(&mut self, read
: bool
) -> &mut Self {
783 /// Sets the option for write access.
785 /// This option, when true, will indicate that the file should be
786 /// `write`-able if opened.
788 /// If the file already exists, any write calls on it will overwrite its
789 /// contents, without truncating it.
794 /// use std::fs::OpenOptions;
796 /// let file = OpenOptions::new().write(true).open("foo.txt");
798 #[stable(feature = "rust1", since = "1.0.0")]
799 pub fn write(&mut self, write
: bool
) -> &mut Self {
804 /// Sets the option for the append mode.
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)`.
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
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.
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.
828 /// This function doesn't create the file if it doesn't exist. Use the
829 /// [`OpenOptions::create`] method to do so.
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"
839 /// use std::fs::OpenOptions;
841 /// let file = OpenOptions::new().append(true).open("foo.txt");
843 #[stable(feature = "rust1", since = "1.0.0")]
844 pub fn append(&mut self, append
: bool
) -> &mut Self {
845 self.0.append(append
);
849 /// Sets the option for truncating a previous file.
851 /// If a file is successfully opened with this option set it will truncate
852 /// the file to 0 length if it already exists.
854 /// The file must be opened with write access for truncate to work.
859 /// use std::fs::OpenOptions;
861 /// let file = OpenOptions::new().write(true).truncate(true).open("foo.txt");
863 #[stable(feature = "rust1", since = "1.0.0")]
864 pub fn truncate(&mut self, truncate
: bool
) -> &mut Self {
865 self.0.truncate(truncate
);
869 /// Sets the option to create a new file, or open it if it already exists.
871 /// In order for the file to be created, [`OpenOptions::write`] or
872 /// [`OpenOptions::append`] access must be used.
877 /// use std::fs::OpenOptions;
879 /// let file = OpenOptions::new().write(true).create(true).open("foo.txt");
881 #[stable(feature = "rust1", since = "1.0.0")]
882 pub fn create(&mut self, create
: bool
) -> &mut Self {
883 self.0.create(create
);
887 /// Sets the option to create a new file, failing if it already exists.
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.
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).
896 /// If `.create_new(true)` is set, [`.create()`] and [`.truncate()`] are
899 /// The file must be opened with write or append access in order to create
902 /// [`.create()`]: OpenOptions::create
903 /// [`.truncate()`]: OpenOptions::truncate
908 /// use std::fs::OpenOptions;
910 /// let file = OpenOptions::new().write(true)
911 /// .create_new(true)
912 /// .open("foo.txt");
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
);
920 /// Opens a file at `path` with the options specified by `self`.
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.
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
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
939 /// * [`InvalidInput`]: Invalid combinations of open options (truncate
940 /// without write access, no access mode set, etc.).
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.
953 /// use std::fs::OpenOptions;
955 /// let file = OpenOptions::new().read(true).open("foo.txt");
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())
967 fn _open(&self, path
: &Path
) -> io
::Result
<File
> {
968 fs_imp
::File
::open(path
, &self.0).map(|inner
| File { inner }
)
972 impl AsInner
<fs_imp
::OpenOptions
> for OpenOptions
{
973 fn as_inner(&self) -> &fs_imp
::OpenOptions
{
978 impl AsInnerMut
<fs_imp
::OpenOptions
> for OpenOptions
{
979 fn as_inner_mut(&mut self) -> &mut fs_imp
::OpenOptions
{
985 /// Returns the file type for this metadata.
990 /// fn main() -> std::io::Result<()> {
993 /// let metadata = fs::metadata("foo.txt")?;
995 /// println!("{:?}", metadata.file_type());
1000 #[stable(feature = "file_type", since = "1.1.0")]
1001 pub fn file_type(&self) -> FileType
{
1002 FileType(self.0.file_type
())
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`].
1013 /// fn main() -> std::io::Result<()> {
1016 /// let metadata = fs::metadata("foo.txt")?;
1018 /// assert!(!metadata.is_dir());
1023 #[stable(feature = "rust1", since = "1.0.0")]
1024 pub fn is_dir(&self) -> bool
{
1025 self.file_type().is_dir()
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`].
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.
1044 /// fn main() -> std::io::Result<()> {
1045 /// let metadata = fs::metadata("foo.txt")?;
1047 /// assert!(metadata.is_file());
1052 #[stable(feature = "rust1", since = "1.0.0")]
1053 pub fn is_file(&self) -> bool
{
1054 self.file_type().is_file()
1057 /// Returns `true` if this metadata is for a symbolic link.
1061 #[cfg_attr(unix, doc = "```no_run")]
1062 #[cfg_attr(not(unix), doc = "```ignore")]
1064 /// use std::path::Path;
1065 /// use std::os::unix::fs::symlink;
1067 /// fn main() -> std::io::Result<()> {
1068 /// let link_path = Path::new("link");
1069 /// symlink("/origin_does_not_exist/", link_path)?;
1071 /// let metadata = fs::symlink_metadata(link_path)?;
1073 /// assert!(metadata.is_symlink());
1078 #[stable(feature = "is_symlink", since = "1.58.0")]
1079 pub fn is_symlink(&self) -> bool
{
1080 self.file_type().is_symlink()
1083 /// Returns the size of the file, in bytes, this metadata is for.
1090 /// fn main() -> std::io::Result<()> {
1091 /// let metadata = fs::metadata("foo.txt")?;
1093 /// assert_eq!(0, metadata.len());
1098 #[stable(feature = "rust1", since = "1.0.0")]
1099 pub fn len(&self) -> u64 {
1103 /// Returns the permissions of the file this metadata is for.
1110 /// fn main() -> std::io::Result<()> {
1111 /// let metadata = fs::metadata("foo.txt")?;
1113 /// assert!(!metadata.permissions().readonly());
1118 #[stable(feature = "rust1", since = "1.0.0")]
1119 pub fn permissions(&self) -> Permissions
{
1120 Permissions(self.0.perm())
1123 /// Returns the last modification time listed in this metadata.
1125 /// The returned value corresponds to the `mtime` field of `stat` on Unix
1126 /// platforms and the `ftLastWriteTime` field on Windows platforms.
1130 /// This field might not be available on all platforms, and will return an
1131 /// `Err` on platforms where it is not available.
1138 /// fn main() -> std::io::Result<()> {
1139 /// let metadata = fs::metadata("foo.txt")?;
1141 /// if let Ok(time) = metadata.modified() {
1142 /// println!("{time:?}");
1144 /// println!("Not supported on this platform");
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
)
1154 /// Returns the last access time of this metadata.
1156 /// The returned value corresponds to the `atime` field of `stat` on Unix
1157 /// platforms and the `ftLastAccessTime` field on Windows platforms.
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`.
1165 /// This field might not be available on all platforms, and will return an
1166 /// `Err` on platforms where it is not available.
1173 /// fn main() -> std::io::Result<()> {
1174 /// let metadata = fs::metadata("foo.txt")?;
1176 /// if let Ok(time) = metadata.accessed() {
1177 /// println!("{time:?}");
1179 /// println!("Not supported on this platform");
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
)
1189 /// Returns the creation time listed in this metadata.
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.
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.
1205 /// fn main() -> std::io::Result<()> {
1206 /// let metadata = fs::metadata("foo.txt")?;
1208 /// if let Ok(time) = metadata.created() {
1209 /// println!("{time:?}");
1211 /// println!("Not supported on this platform or filesystem");
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
)
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()
1237 impl AsInner
<fs_imp
::FileAttr
> for Metadata
{
1238 fn as_inner(&self) -> &fs_imp
::FileAttr
{
1243 impl FromInner
<fs_imp
::FileAttr
> for Metadata
{
1244 fn from_inner(attr
: fs_imp
::FileAttr
) -> Metadata
{
1250 /// Returns `true` if these permissions describe a readonly (unwritable) file.
1255 /// use std::fs::File;
1257 /// fn main() -> std::io::Result<()> {
1258 /// let mut f = File::create("foo.txt")?;
1259 /// let metadata = f.metadata()?;
1261 /// assert_eq!(false, metadata.permissions().readonly());
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
{
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
1277 /// This operation does **not** modify the filesystem. To modify the
1278 /// filesystem use the [`set_permissions`] function.
1283 /// use std::fs::File;
1285 /// fn main() -> std::io::Result<()> {
1286 /// let f = File::create("foo.txt")?;
1287 /// let metadata = f.metadata()?;
1288 /// let mut permissions = metadata.permissions();
1290 /// permissions.set_readonly(true);
1292 /// // filesystem doesn't change
1293 /// assert_eq!(false, metadata.permissions().readonly());
1295 /// // just this particular `permissions`.
1296 /// assert_eq!(true, permissions.readonly());
1300 #[stable(feature = "rust1", since = "1.0.0")]
1301 pub fn set_readonly(&mut self, readonly
: bool
) {
1302 self.0.set_readonly(readonly
)
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
1312 /// [`is_file`]: FileType::is_file
1313 /// [`is_symlink`]: FileType::is_symlink
1318 /// fn main() -> std::io::Result<()> {
1321 /// let metadata = fs::metadata("foo.txt")?;
1322 /// let file_type = metadata.file_type();
1324 /// assert_eq!(file_type.is_dir(), false);
1329 #[stable(feature = "file_type", since = "1.1.0")]
1330 pub fn is_dir(&self) -> bool
{
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
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.
1345 /// [`is_dir`]: FileType::is_dir
1346 /// [`is_symlink`]: FileType::is_symlink
1351 /// fn main() -> std::io::Result<()> {
1354 /// let metadata = fs::metadata("foo.txt")?;
1355 /// let file_type = metadata.file_type();
1357 /// assert_eq!(file_type.is_file(), true);
1362 #[stable(feature = "file_type", since = "1.1.0")]
1363 pub fn is_file(&self) -> bool
{
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
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.
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
1389 /// fn main() -> std::io::Result<()> {
1390 /// let metadata = fs::symlink_metadata("foo.txt")?;
1391 /// let file_type = metadata.file_type();
1393 /// assert_eq!(file_type.is_symlink(), false);
1398 #[stable(feature = "file_type", since = "1.1.0")]
1399 pub fn is_symlink(&self) -> bool
{
1404 impl AsInner
<fs_imp
::FileType
> for FileType
{
1405 fn as_inner(&self) -> &fs_imp
::FileType
{
1410 impl FromInner
<fs_imp
::FilePermissions
> for Permissions
{
1411 fn from_inner(f
: fs_imp
::FilePermissions
) -> Permissions
{
1416 impl AsInner
<fs_imp
::FilePermissions
> for Permissions
{
1417 fn as_inner(&self) -> &fs_imp
::FilePermissions
{
1422 #[stable(feature = "rust1", since = "1.0.0")]
1423 impl Iterator
for ReadDir
{
1424 type Item
= io
::Result
<DirEntry
>;
1426 fn next(&mut self) -> Option
<io
::Result
<DirEntry
>> {
1427 self.0.next().map(|entry
| entry
.map(DirEntry
))
1432 /// Returns the full path to the file that this entry represents.
1434 /// The full path is created by joining the original path to `read_dir`
1435 /// with the filename of this entry.
1442 /// fn main() -> std::io::Result<()> {
1443 /// for entry in fs::read_dir(".")? {
1444 /// let dir = entry?;
1445 /// println!("{:?}", dir.path());
1451 /// This prints output like:
1454 /// "./whatever.txt"
1456 /// "./hello_world.rs"
1459 /// The exact text, of course, depends on what files you have in `.`.
1461 #[stable(feature = "rust1", since = "1.0.0")]
1462 pub fn path(&self) -> PathBuf
{
1466 /// Returns the metadata for the file that this entry points at.
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`].
1471 /// [`fs::metadata`]: metadata
1472 /// [`fs::File::metadata`]: File::metadata
1474 /// # Platform-specific behavior
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.
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());
1493 /// println!("Couldn't get metadata for {:?}", entry.path());
1499 #[stable(feature = "dir_entry_ext", since = "1.1.0")]
1500 pub fn metadata(&self) -> io
::Result
<Metadata
> {
1501 self.0.metadata().map(Metadata
)
1504 /// Returns the file type for the file that this entry points at.
1506 /// This function will not traverse symlinks if this entry points at a
1509 /// # Platform-specific behavior
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.
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);
1528 /// println!("Couldn't get file type for {:?}", entry.path());
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
)
1539 /// Returns the bare file name of this directory entry without any other
1540 /// leading path component.
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());
1557 #[stable(feature = "dir_entry_ext", since = "1.1.0")]
1558 pub fn file_name(&self) -> OsString
{
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()
1570 impl AsInner
<fs_imp
::DirEntry
> for DirEntry
{
1571 fn as_inner(&self) -> &fs_imp
::DirEntry
{
1576 /// Removes a file from the filesystem.
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).
1582 /// # Platform-specific behavior
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].
1588 /// [changes]: io#platform-specific-behavior
1592 /// This function will return an error in the following situations, but is not
1593 /// limited to just these cases:
1595 /// * `path` points to a directory.
1596 /// * The file doesn't exist.
1597 /// * The user lacks permissions to remove the file.
1604 /// fn main() -> std::io::Result<()> {
1605 /// fs::remove_file("a.txt")?;
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())
1614 /// Given a path, query the file system to get information about a file,
1617 /// This function will traverse symbolic links to query information about the
1618 /// destination file.
1620 /// # Platform-specific behavior
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].
1626 /// [changes]: io#platform-specific-behavior
1630 /// This function will return an error in the following situations, but is not
1631 /// limited to just these cases:
1633 /// * The user lacks permissions to perform `metadata` call on `path`.
1634 /// * `path` does not exist.
1641 /// fn main() -> std::io::Result<()> {
1642 /// let attr = fs::metadata("/some/file/path.txt")?;
1643 /// // inspect attr ...
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
)
1652 /// Query the metadata about a file without following symlinks.
1654 /// # Platform-specific behavior
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].
1660 /// [changes]: io#platform-specific-behavior
1664 /// This function will return an error in the following situations, but is not
1665 /// limited to just these cases:
1667 /// * The user lacks permissions to perform `metadata` call on `path`.
1668 /// * `path` does not exist.
1675 /// fn main() -> std::io::Result<()> {
1676 /// let attr = fs::symlink_metadata("/some/file/path.txt")?;
1677 /// // inspect attr ...
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
)
1686 /// Rename a file or directory to a new name, replacing the original file if
1687 /// `to` already exists.
1689 /// This will not work if the new name is on a different mount point.
1691 /// # Platform-specific behavior
1693 /// This function currently corresponds to the `rename` function on Unix
1694 /// and the `MoveFileEx` function with the `MOVEFILE_REPLACE_EXISTING` flag on Windows.
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.
1701 /// Note that, this [may change in the future][changes].
1703 /// [changes]: io#platform-specific-behavior
1707 /// This function will return an error in the following situations, but is not
1708 /// limited to just these cases:
1710 /// * `from` does not exist.
1711 /// * The user lacks permissions to view contents.
1712 /// * `from` and `to` are on separate filesystems.
1719 /// fn main() -> std::io::Result<()> {
1720 /// fs::rename("a.txt", "b.txt")?; // Rename a.txt to b.txt
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())
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.
1732 /// This function will **overwrite** the contents of `to`.
1734 /// Note that if `from` and `to` both point to the same file, then the file
1735 /// will likely get truncated by this operation.
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`.
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.
1743 /// # Platform-specific behavior
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.
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.
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
1756 /// On MacOS, this function corresponds to `fclonefileat` and `fcopyfile`.
1758 /// Note that platform-specific behavior [may change in the future][changes].
1760 /// [changes]: io#platform-specific-behavior
1764 /// This function will return an error in the following situations, but is not
1765 /// limited to just these cases:
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`.
1777 /// fn main() -> std::io::Result<()> {
1778 /// fs::copy("foo.txt", "bar.txt")?; // Copy foo.txt to bar.txt
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())
1787 /// Creates a new hard link on the filesystem.
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
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
1798 /// # Platform-specific behavior
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].
1807 /// [changes]: io#platform-specific-behavior
1811 /// This function will return an error in the following situations, but is not
1812 /// limited to just these cases:
1814 /// * The `original` path is not a file or doesn't exist.
1821 /// fn main() -> std::io::Result<()> {
1822 /// fs::hard_link("a.txt", "b.txt")?; // Hard link a.txt to b.txt
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())
1831 /// Creates a new symbolic link on the filesystem.
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.
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
1848 /// fn main() -> std::io::Result<()> {
1849 /// fs::soft_link("a.txt", "b.txt")?;
1853 #[stable(feature = "rust1", since = "1.0.0")]
1856 note
= "replaced with std::os::unix::fs::symlink and \
1857 std::os::windows::fs::{symlink_file, symlink_dir}"
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())
1863 /// Reads a symbolic link, returning the file that the link points to.
1865 /// # Platform-specific behavior
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].
1872 /// [changes]: io#platform-specific-behavior
1876 /// This function will return an error in the following situations, but is not
1877 /// limited to just these cases:
1879 /// * `path` is not a symbolic link.
1880 /// * `path` does not exist.
1887 /// fn main() -> std::io::Result<()> {
1888 /// let path = fs::read_link("a.txt")?;
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())
1897 /// Returns the canonical, absolute form of a path with all intermediate
1898 /// components normalized and symbolic links resolved.
1900 /// # Platform-specific behavior
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].
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).
1912 /// [changes]: io#platform-specific-behavior
1913 /// [path]: https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file
1917 /// This function will return an error in the following situations, but is not
1918 /// limited to just these cases:
1920 /// * `path` does not exist.
1921 /// * A non-final component in path is not a directory.
1928 /// fn main() -> std::io::Result<()> {
1929 /// let path = fs::canonicalize("../a/../foo.txt")?;
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())
1940 /// Creates a new, empty directory at the provided path
1942 /// # Platform-specific behavior
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].
1948 /// [changes]: io#platform-specific-behavior
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.
1956 /// This function will return an error in the following situations, but is not
1957 /// limited to just these cases:
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`]
1963 /// * `path` already exists.
1970 /// fn main() -> std::io::Result<()> {
1971 /// fs::create_dir("/some/dir")?;
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())
1981 /// Recursively create a directory and all of its parent components if they
1984 /// # Platform-specific behavior
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].
1990 /// [changes]: io#platform-specific-behavior
1994 /// This function will return an error in the following situations, but is not
1995 /// limited to just these cases:
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`].
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.
2008 /// [`fs::create_dir`]: create_dir
2015 /// fn main() -> std::io::Result<()> {
2016 /// fs::create_dir_all("/some/dir")?;
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())
2025 /// Removes an empty directory.
2027 /// # Platform-specific behavior
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].
2033 /// [changes]: io#platform-specific-behavior
2037 /// This function will return an error in the following situations, but is not
2038 /// limited to just these cases:
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.
2050 /// fn main() -> std::io::Result<()> {
2051 /// fs::remove_dir("/some/dir")?;
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())
2061 /// Removes a directory at this path, after removing all its contents. Use
2064 /// This function does **not** follow symbolic links and it will simply remove the
2065 /// symbolic link itself.
2067 /// # Platform-specific behavior
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].
2074 /// [changes]: io#platform-specific-behavior
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
2083 /// See [`fs::remove_file`] and [`fs::remove_dir`].
2085 /// [`fs::remove_file`]: remove_file
2086 /// [`fs::remove_dir`]: remove_dir
2093 /// fn main() -> std::io::Result<()> {
2094 /// fs::remove_dir_all("/some/dir")?;
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())
2103 /// Returns an iterator over the entries within a directory.
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
2110 /// # Platform-specific behavior
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].
2117 /// [changes]: io#platform-specific-behavior
2119 /// The order in which this iterator returns entries is platform and filesystem
2124 /// This function will return an error in the following situations, but is not
2125 /// limited to just these cases:
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.
2135 /// use std::fs::{self, DirEntry};
2136 /// use std::path::Path;
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)?;
2156 /// use std::{fs, io};
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>>()?;
2163 /// // The order in which `read_dir` returns entries is not guaranteed. If reproducible
2164 /// // ordering is required the entries should be explicitly sorted.
2168 /// // The entries have now been sorted by their path.
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
)
2178 /// Changes the permissions found on a file or a directory.
2180 /// # Platform-specific behavior
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].
2186 /// [changes]: io#platform-specific-behavior
2190 /// This function will return an error in the following situations, but is not
2191 /// limited to just these cases:
2193 /// * `path` does not exist.
2194 /// * The user lacks the permission to change attributes of the file.
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)?;
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)
2214 /// Creates a new set of options with default mode/security settings for all
2215 /// platforms and also non-recursive.
2220 /// use std::fs::DirBuilder;
2222 /// let builder = DirBuilder::new();
2224 #[stable(feature = "dir_builder", since = "1.6.0")]
2226 pub fn new() -> DirBuilder
{
2227 DirBuilder { inner: fs_imp::DirBuilder::new(), recursive: false }
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.
2234 /// This option defaults to `false`.
2239 /// use std::fs::DirBuilder;
2241 /// let mut builder = DirBuilder::new();
2242 /// builder.recursive(true);
2244 #[stable(feature = "dir_builder", since = "1.6.0")]
2245 pub fn recursive(&mut self, recursive
: bool
) -> &mut Self {
2246 self.recursive
= recursive
;
2250 /// Creates the specified directory with the options configured in this
2253 /// It is considered an error if the directory already exists unless
2254 /// recursive mode is enabled.
2259 /// use std::fs::{self, DirBuilder};
2261 /// let path = "/tmp/foo/bar/baz";
2262 /// DirBuilder::new()
2263 /// .recursive(true)
2264 /// .create(path).unwrap();
2266 /// assert!(fs::metadata(path).unwrap().is_dir());
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())
2273 fn _create(&self, path
: &Path
) -> io
::Result
<()> {
2274 if self.recursive { self.create_dir_all(path) }
else { self.inner.mkdir(path) }
2277 fn create_dir_all(&self, path
: &Path
) -> io
::Result
<()> {
2278 if path
== Path
::new("") {
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
),
2288 match path
.parent() {
2289 Some(p
) => self.create_dir_all(p
)?
,
2291 return Err(io
::const_io_error
!(
2292 io
::ErrorKind
::Uncategorized
,
2293 "failed to create whole tree",
2297 match self.inner
.mkdir(path
) {
2299 Err(_
) if path
.is_dir() => Ok(()),
2305 impl AsInnerMut
<fs_imp
::DirBuilder
> for DirBuilder
{
2306 fn as_inner_mut(&mut self) -> &mut fs_imp
::DirBuilder
{
2311 /// Returns `Ok(true)` if the path points at an existing entity.
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)`.
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.)
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.
2327 /// #![feature(fs_try_exists)]
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());
2334 /// [`Path::exists`]: crate::path::Path::exists
2335 // FIXME: stabilization should modify documentation of `exists()` to recommend this method
2337 #[unstable(feature = "fs_try_exists", issue = "83186")]
2339 pub fn try_exists
<P
: AsRef
<Path
>>(path
: P
) -> io
::Result
<bool
> {
2340 fs_imp
::try_exists(path
.as_ref())