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