Shortest code to read and write a file

Is that the shortest way to get a Vec<u8> contents of a file at run time?

fn main() {
    use std::io::Read;
    let mut c = Vec::new();
    std::fs::File::open("f").unwrap().read_to_end(&mut c).unwrap();
}

I'm asking, because I found myself writing these 3 lines in every program I write. Before I make myself a helper crate with one-stop function, I'd like to be sure I'm not reinventing something that's already in stdlib.

2 Likes

I make the same bug in every repl like program! :grinning:

let mut buffer = String::new();

loop {
    buffer.clear(); // <- always forget this ;(
    std::io::stdin().read_line(&mut buffer).unwrap();
    ...
}

So I've created

extern crate file;
file::get("path");

That's 2 lines instead of 3 :wink:

edit: it's now std::fs::write(path, data)

2 Likes

Docs and repo links please?

Added

Great! You might want to:

  • Use io::Result<T> instead of Result<T, io::Error>
  • experiment with preallocating the buffer for reading (querying OS for the file size) because the standard implementation uses reallocation (and I'm not sure which approach is more efficient).

It should go in standard library.

1 Like

See

https://github.com/rust-lang/rust/issues/34857

1 Like

When I was doing tests on a 29MB file in Linux a few weeks ago, the preallocation approach was several times more efficient (~10ms versus ~40ms).

let metadata = try!(fs::metadata(&path));
let mut buf = Vec::with_capacity(metadata.len() as usize + 1);
// note: File's read_to_end uses the buffer capacity to choose how much to read
try!(fh.read_to_end(&mut buf));

Note, read_to_end detects EOF by trying to read into the part of the vector after the len and getting a zero byte result. This means that there will always be at least one byte of slack, and if you don't preallocate a byte of slack there will be an unneeded reallocate at the very end.

Surely it's way faster on a large file. The question is how well it behaves on smaller files, because there the performance cost of an additional system call may not be negligible.

2 Likes

Use read_exact() then