Skip to content

Commit da0e548

Browse files
authored
Rollup merge of rust-lang#47324 - mbrubeck:len, r=sfackler
Pre-allocate in fs::read and fs::read_string This is a simpler alternative to rust-lang#46340 and rust-lang#45928, as requested by the libs team.
2 parents 56e8f5d + 44912bf commit da0e548

File tree

1 file changed

+10
-2
lines changed

1 file changed

+10
-2
lines changed

src/libstd/fs.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,14 @@ pub struct DirBuilder {
211211
recursive: bool,
212212
}
213213

214+
/// How large a buffer to pre-allocate before reading the entire file at `path`.
215+
fn initial_buffer_size<P: AsRef<Path>>(path: P) -> usize {
216+
// Allocate one extra byte so the buffer doesn't need to grow before the
217+
// final `read` call at the end of the file. Don't worry about `usize`
218+
// overflow because reading will fail regardless in that case.
219+
metadata(path).map(|m| m.len() as usize + 1).unwrap_or(0)
220+
}
221+
214222
/// Read the entire contents of a file into a bytes vector.
215223
///
216224
/// This is a convenience function for using [`File::open`] and [`read_to_end`]
@@ -246,7 +254,7 @@ pub struct DirBuilder {
246254
/// ```
247255
#[unstable(feature = "fs_read_write", issue = "46588")]
248256
pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
249-
let mut bytes = Vec::new();
257+
let mut bytes = Vec::with_capacity(initial_buffer_size(&path));
250258
File::open(path)?.read_to_end(&mut bytes)?;
251259
Ok(bytes)
252260
}
@@ -287,7 +295,7 @@ pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
287295
/// ```
288296
#[unstable(feature = "fs_read_write", issue = "46588")]
289297
pub fn read_string<P: AsRef<Path>>(path: P) -> io::Result<String> {
290-
let mut string = String::new();
298+
let mut string = String::with_capacity(initial_buffer_size(&path));
291299
File::open(path)?.read_to_string(&mut string)?;
292300
Ok(string)
293301
}

0 commit comments

Comments
 (0)