Merge branch 'master' into is-symlink-stabilization
This commit is contained in:
@@ -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 }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user