Reputation: 4484
I'm trying to take an image that is converted into a vector of bytes and write those bytes to a new file. The first part is working, and my code is compiling, but the new file that is created ends up empty (nothing is written to it). What am I missing?
Is there a cleaner way to convert Vec<u8>
into &[u8]
so that it can be written? The way I'm currently doing it seems kind of ridiculous...
use std::os;
use std::io::BufferedReader;
use std::io::File;
use std::io::BufferedWriter;
fn get_file_buffer(path_str: String) -> Vec<u8> {
let path = Path::new(path_str.as_bytes());
let file = File::open(&path);
let mut reader = BufferedReader::new(file);
match reader.read_to_end() {
Ok(x) => x,
Err(_) => vec![0],
}
}
fn main() {
let file = get_file_buffer(os::args()[1].clone());
let mut new_file = File::create(&Path::new("foo.png")).unwrap();
let mut writer = BufferedWriter::new(new_file);
writer.write(String::from_utf8(file).unwrap().as_bytes()).unwrap();
writer.flush().unwrap();
}
Upvotes: 1
Views: 4964
Reputation: 90742
Given a Vec<T>
, you can get a &[T]
out of it in two ways:
Take a reference to a dereference of it, i.e. &*file
; this works because Vec<T>
implements Deref<[T]>
, so *file
is effectively of type [T]
(though doing that without borrowing it, i.e. &*file
, is not legal).
Call the as_slice()
method.
As the BufWriter
docs say, “the buffer will be written out when the writer is dropped”, so that writer.flush().unwrap()
is not strictly necessary, serving only to make handling of errors explicit.
But as for the behaviour you describe, that I mostly do not observe. So long as you do not encounter any I/O errors, the version not using the String
dance will work fine, while with the String
dance it will panic if the input data is not legal UTF-8 (which if you’re dealing with images it probably won’t be). String::from_utf8
returns None
in such cases, and so unwrapping that panics.
Upvotes: 4