@@ -262,6 +262,73 @@ impl File {
262262 OpenOptions :: new ( ) . write ( true ) . create ( true ) . truncate ( true ) . open ( path. as_ref ( ) )
263263 }
264264
265+ /// Read the entire contents of a file into a bytes vector.
266+ ///
267+ /// This is a convenience function for using [`File::open`] and [`read_to_end`]
268+ /// with fewer imports and without an intermediate variable.
269+ ///
270+ /// [`File::open`]: struct.File.html#method.open
271+ /// [`read_to_end`]: ../io/trait.Read.html#method.read_to_end
272+ ///
273+ /// # Errors
274+ ///
275+ /// This function will return an error if `path` does not already exist.
276+ /// Other errors may also be returned according to [`OpenOptions::open`].
277+ ///
278+ /// [`OpenOptions::open`]: struct.OpenOptions.html#method.open
279+ ///
280+ /// It will also return an error if it encounters while reading an error
281+ /// of a kind other than [`ErrorKind::Interrupted`].
282+ ///
283+ /// [`ErrorKind::Interrupted`]: ../../std/io/enum.ErrorKind.html#variant.Interrupted
284+ ///
285+ /// # Examples
286+ ///
287+ /// ```no_run
288+ /// #![feature(file_read_write_contents)]
289+ ///
290+ /// use std::fs::File;
291+ ///
292+ /// # fn foo() -> Result<(), Box<std::error::Error + 'static>> {
293+ /// let foo = String::from_utf8(File::read_contents("foo.txt")?)?;
294+ /// # Ok(())
295+ /// # }
296+ /// ```
297+ #[ unstable( feature = "file_read_write_contents" , issue = /* FIXME */ "0" ) ]
298+ pub fn read_contents < P : AsRef < Path > > ( path : P ) -> io:: Result < Vec < u8 > > {
299+ let mut bytes = Vec :: new ( ) ;
300+ File :: open ( path) ?. read_to_end ( & mut bytes) ?;
301+ Ok ( bytes)
302+ }
303+
304+ /// Write the give contents to a file.
305+ ///
306+ /// This function will create a file if it does not exist,
307+ /// and will entirely replace its contents if it does.
308+ ///
309+ /// This is a convenience function for using [`File::create`] and [`write_all`]
310+ /// with fewer imports.
311+ ///
312+ /// [`File::create`]: struct.File.html#method.create
313+ /// [`write_all`]: ../io/trait.Write.html#method.write_all
314+ ///
315+ /// # Examples
316+ ///
317+ /// ```no_run
318+ /// #![feature(file_read_write_contents)]
319+ ///
320+ /// use std::fs::File;
321+ ///
322+ /// # fn foo() -> std::io::Result<()> {
323+ /// File::write_contents("foo.txt", b"Lorem ipsum")?;
324+ /// # Ok(())
325+ /// # }
326+ /// ```
327+ #[ unstable( feature = "file_read_write_contents" , issue = /* FIXME */ "0" ) ]
328+ pub fn write_contents < P : AsRef < Path > > ( path : P , contents : & [ u8 ] ) -> io:: Result < ( ) > {
329+ File :: create ( path) ?. write_all ( contents)
330+ }
331+
265332 /// Attempts to sync all OS-internal metadata to disk.
266333 ///
267334 /// This function will attempt to ensure that all in-core data reaches the
@@ -2921,6 +2988,18 @@ mod tests {
29212988 assert ! ( v == & bytes[ ..] ) ;
29222989 }
29232990
2991+ #[ test]
2992+ fn write_contents_then_read_contents ( ) {
2993+ let mut bytes = [ 0 ; 1024 ] ;
2994+ StdRng :: new ( ) . unwrap ( ) . fill_bytes ( & mut bytes) ;
2995+
2996+ let tmpdir = tmpdir ( ) ;
2997+
2998+ check ! ( File :: write_contents( & tmpdir. join( "test" ) , & bytes) ) ;
2999+ let v = check ! ( File :: read_contents( & tmpdir. join( "test" ) ) ) ;
3000+ assert ! ( v == & bytes[ ..] ) ;
3001+ }
3002+
29243003 #[ test]
29253004 fn file_try_clone ( ) {
29263005 let tmpdir = tmpdir ( ) ;
0 commit comments