Merge branch 'master' into is-symlink-stabilization

This commit is contained in:
Max Wase
2021-10-13 01:33:12 +03:00
committed by GitHub
365 changed files with 4893 additions and 3106 deletions

View File

@@ -198,19 +198,10 @@ pub struct DirBuilder {
recursive: bool,
}
/// Indicates how large a buffer to pre-allocate before reading the entire file.
fn initial_buffer_size(file: &File) -> usize {
// Don't worry about `usize` overflow because reading will fail regardless
// in that case.
file.metadata().map(|m| m.len() as usize).unwrap_or(0)
}
/// Read the entire contents of a file into a bytes vector.
///
/// This is a convenience function for using [`File::open`] and [`read_to_end`]
/// with fewer imports and without an intermediate variable. It pre-allocates a
/// buffer based on the file size when available, so it is generally faster than
/// reading into a vector created with [`Vec::new()`].
/// with fewer imports and without an intermediate variable.
///
/// [`read_to_end`]: Read::read_to_end
///
@@ -237,7 +228,7 @@ fn initial_buffer_size(file: &File) -> usize {
pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
fn inner(path: &Path) -> io::Result<Vec<u8>> {
let mut file = File::open(path)?;
let mut bytes = Vec::with_capacity(initial_buffer_size(&file));
let mut bytes = Vec::new();
file.read_to_end(&mut bytes)?;
Ok(bytes)
}
@@ -247,9 +238,7 @@ pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
/// Read the entire contents of a file into a string.
///
/// This is a convenience function for using [`File::open`] and [`read_to_string`]
/// with fewer imports and without an intermediate variable. It pre-allocates a
/// buffer based on the file size when available, so it is generally faster than
/// reading into a string created with [`String::new()`].
/// with fewer imports and without an intermediate variable.
///
/// [`read_to_string`]: Read::read_to_string
///
@@ -278,7 +267,7 @@ pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
pub fn read_to_string<P: AsRef<Path>>(path: P) -> io::Result<String> {
fn inner(path: &Path) -> io::Result<String> {
let mut file = File::open(path)?;
let mut string = String::with_capacity(initial_buffer_size(&file));
let mut string = String::new();
file.read_to_string(&mut string)?;
Ok(string)
}
@@ -615,6 +604,15 @@ impl fmt::Debug for File {
}
}
/// Indicates how much extra capacity is needed to read the rest of the file.
fn buffer_capacity_required(mut file: &File) -> usize {
let size = file.metadata().map(|m| m.len()).unwrap_or(0);
let pos = file.stream_position().unwrap_or(0);
// Don't worry about `usize` overflow because reading will fail regardless
// in that case.
size.saturating_sub(pos) as usize
}
#[stable(feature = "rust1", since = "1.0.0")]
impl Read for File {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
@@ -635,6 +633,18 @@ impl Read for File {
// SAFETY: Read is guaranteed to work on uninitialized memory
unsafe { Initializer::nop() }
}
// Reserves space in the buffer based on the file size when available.
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
buf.reserve(buffer_capacity_required(self));
io::default_read_to_end(self, buf)
}
// Reserves space in the buffer based on the file size when available.
fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
buf.reserve(buffer_capacity_required(self));
io::default_read_to_string(self, buf)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl Write for File {
@@ -681,6 +691,18 @@ impl Read for &File {
// SAFETY: Read is guaranteed to work on uninitialized memory
unsafe { Initializer::nop() }
}
// Reserves space in the buffer based on the file size when available.
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
buf.reserve(buffer_capacity_required(self));
io::default_read_to_end(self, buf)
}
// Reserves space in the buffer based on the file size when available.
fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
buf.reserve(buffer_capacity_required(self));
io::default_read_to_string(self, buf)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl Write for &File {
@@ -722,6 +744,7 @@ impl OpenOptions {
/// let file = options.read(true).open("foo.txt");
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use]
pub fn new() -> Self {
OpenOptions(fs_imp::OpenOptions::new())
}
@@ -982,6 +1005,7 @@ impl Metadata {
/// Ok(())
/// }
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn is_dir(&self) -> bool {
self.file_type().is_dir()
@@ -1010,6 +1034,7 @@ impl Metadata {
/// Ok(())
/// }
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn is_file(&self) -> bool {
self.file_type().is_file()
@@ -1035,6 +1060,7 @@ impl Metadata {
/// Ok(())
/// }
/// ```
#[must_use]
#[stable(feature = "is_symlink", since = "1.57.0")]
pub fn is_symlink(&self) -> bool {
self.file_type().is_symlink()
@@ -1282,6 +1308,7 @@ impl FileType {
/// Ok(())
/// }
/// ```
#[must_use]
#[stable(feature = "file_type", since = "1.1.0")]
pub fn is_dir(&self) -> bool {
self.0.is_dir()
@@ -1314,6 +1341,7 @@ impl FileType {
/// Ok(())
/// }
/// ```
#[must_use]
#[stable(feature = "file_type", since = "1.1.0")]
pub fn is_file(&self) -> bool {
self.0.is_file()
@@ -1349,6 +1377,7 @@ impl FileType {
/// Ok(())
/// }
/// ```
#[must_use]
#[stable(feature = "file_type", since = "1.1.0")]
pub fn is_symlink(&self) -> bool {
self.0.is_symlink()
@@ -2161,6 +2190,7 @@ impl DirBuilder {
/// let builder = DirBuilder::new();
/// ```
#[stable(feature = "dir_builder", since = "1.6.0")]
#[must_use]
pub fn new() -> DirBuilder {
DirBuilder { inner: fs_imp::DirBuilder::new(), recursive: false }
}