about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorSimon Sapin <simon.sapin@exyr.org>2017-11-07 16:17:03 +0100
committerSimon Sapin <simon.sapin@exyr.org>2017-11-07 17:52:07 +0100
commitfd518ac4b0fe30b13d2fdf0f1b4b9fa129d75dff (patch)
treea95f09bcd8812dd94a7cf8d180d8847eb295e441 /src/libstd
parent3e7f501991df2f7fc87f6c340945112c128735d2 (diff)
downloadrust-fd518ac4b0fe30b13d2fdf0f1b4b9fa129d75dff.tar.gz
rust-fd518ac4b0fe30b13d2fdf0f1b4b9fa129d75dff.zip
Add File::read_contents and File::write_contents convenience functions.
Before:

```rust
use std::fs::File;
use std::io::Read;

let mut bytes = Vec::new();
File::open(filename)?.read_to_end(&mut bytes)?;
do_something_with(bytes)
```

After:

```rust
use std::fs::File;

do_something_with(File::read_contents(filename)?)
```
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/fs.rs79
-rw-r--r--src/libstd/lib.rs1
2 files changed, 80 insertions, 0 deletions
diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs
index b07733d3c80..9b41cde30fb 100644
--- a/src/libstd/fs.rs
+++ b/src/libstd/fs.rs
@@ -262,6 +262,73 @@ impl File {
         OpenOptions::new().write(true).create(true).truncate(true).open(path.as_ref())
     }
 
+    /// 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.
+    ///
+    /// [`File::open`]: struct.File.html#method.open
+    /// [`read_to_end`]: ../io/trait.Read.html#method.read_to_end
+    ///
+    /// # Errors
+    ///
+    /// This function will return an error if `path` does not already exist.
+    /// Other errors may also be returned according to [`OpenOptions::open`].
+    ///
+    /// [`OpenOptions::open`]: struct.OpenOptions.html#method.open
+    ///
+    /// It will also return an error if it encounters while reading an error
+    /// of a kind other than [`ErrorKind::Interrupted`].
+    ///
+    /// [`ErrorKind::Interrupted`]: ../../std/io/enum.ErrorKind.html#variant.Interrupted
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// #![feature(file_read_write_contents)]
+    ///
+    /// use std::fs::File;
+    ///
+    /// # fn foo() -> Result<(), Box<std::error::Error + 'static>> {
+    /// let foo = String::from_utf8(File::read_contents("foo.txt")?)?;
+    /// # Ok(())
+    /// # }
+    /// ```
+    #[unstable(feature = "file_read_write_contents", issue = /* FIXME */ "0")]
+    pub fn read_contents<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
+        let mut bytes = Vec::new();
+        File::open(path)?.read_to_end(&mut bytes)?;
+        Ok(bytes)
+    }
+
+    /// Write the give contents to a file.
+    ///
+    /// This function will create a file if it does not exist,
+    /// and will entirely replace its contents if it does.
+    ///
+    /// This is a convenience function for using [`File::create`] and [`write_all`]
+    /// with fewer imports.
+    ///
+    /// [`File::create`]: struct.File.html#method.create
+    /// [`write_all`]: ../io/trait.Write.html#method.write_all
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// #![feature(file_read_write_contents)]
+    ///
+    /// use std::fs::File;
+    ///
+    /// # fn foo() -> std::io::Result<()> {
+    /// File::write_contents("foo.txt", b"Lorem ipsum")?;
+    /// # Ok(())
+    /// # }
+    /// ```
+    #[unstable(feature = "file_read_write_contents", issue = /* FIXME */ "0")]
+    pub fn write_contents<P: AsRef<Path>>(path: P, contents: &[u8]) -> io::Result<()> {
+        File::create(path)?.write_all(contents)
+    }
+
     /// Attempts to sync all OS-internal metadata to disk.
     ///
     /// This function will attempt to ensure that all in-core data reaches the
@@ -2922,6 +2989,18 @@ mod tests {
     }
 
     #[test]
+    fn write_contents_then_read_contents() {
+        let mut bytes = [0; 1024];
+        StdRng::new().unwrap().fill_bytes(&mut bytes);
+
+        let tmpdir = tmpdir();
+
+        check!(File::write_contents(&tmpdir.join("test"), &bytes));
+        let v = check!(File::read_contents(&tmpdir.join("test")));
+        assert!(v == &bytes[..]);
+    }
+
+    #[test]
     fn file_try_clone() {
         let tmpdir = tmpdir();
 
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 429153dc58b..698830cc45b 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -269,6 +269,7 @@
 #![feature(core_intrinsics)]
 #![feature(dropck_eyepatch)]
 #![feature(exact_size_is_empty)]
+#![feature(file_read_write_contents)]
 #![feature(fixed_size_array)]
 #![feature(float_from_str_radix)]
 #![feature(fn_traits)]