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