@@ -211,6 +211,14 @@ pub struct DirBuilder {
211
211
recursive : bool ,
212
212
}
213
213
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
+
214
222
/// Read the entire contents of a file into a bytes vector.
215
223
///
216
224
/// This is a convenience function for using [`File::open`] and [`read_to_end`]
@@ -246,7 +254,7 @@ pub struct DirBuilder {
246
254
/// ```
247
255
#[ unstable( feature = "fs_read_write" , issue = "46588" ) ]
248
256
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 ) ) ;
250
258
File :: open ( path) ?. read_to_end ( & mut bytes) ?;
251
259
Ok ( bytes)
252
260
}
@@ -287,7 +295,7 @@ pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
287
295
/// ```
288
296
#[ unstable( feature = "fs_read_write" , issue = "46588" ) ]
289
297
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 ) ) ;
291
299
File :: open ( path) ?. read_to_string ( & mut string) ?;
292
300
Ok ( string)
293
301
}
0 commit comments