Reputation: 2404
I'm trying to write a number to a file. The number in the file I don't want to be represented as UFT-8 or some other encoding. I just want the binary representation of the number written to the file.
The code tries to write to a file and then read the file back to the user.
use std::fs::File;
use std::io::prelude::*;
fn main() -> () {
let number:usize =244128131191;
let mut file = File::create("data").expect("create failed");
file.write_all(&[number]).expect("write failed");
println!("data written to file" );
let mut file = File::open("data").expect("open failed");
let mut buffer = Vec::<usize>::new();
file.read_to_end(&mut buffer);
println!("{:?}", buffer);
}
I get this error back complaining about types used.
Compiling writing_file v0.1.0 (file:///home/9716278/writing_file)
error[E0308]: mismatched types
--> src/main.rs:37:22
|
37 | file.write_all(&[number]).expect("write failed");
| ^^^^^^ expected u8, found usize
error[E0308]: mismatched types
--> src/main.rs:42:22
|
42 | file.read_to_end(&mut buffer);
| ^^^^^^^^^^^ expected u8, found usize
|
= note: expected type `&mut std::vec::Vec<u8>`
found type `&mut std::vec::Vec<usize>`
error: aborting due to 2 previous errors
error: Could not compile `counting_utf`.
To learn more, run the command again with --verbose.
I'm not sure what's going wrong. The problem is to do with types according to the error. I'm not user if this is the right approach for what I'm trying to do.
Upvotes: 3
Views: 3746
Reputation: 134
The file when read is of unknown length (therefore it's read into a vector without a fixed length), but the variable you want at the end is of type usize.
I have shown here that you can convert the vector to a fixed size array and then convert that to a usize variable.
Hopefully someone can improve on this answer!
use std::fs::File;
use std::io::prelude::*;
fn main() -> () {
let number:usize = 244128131191;
// write number to file
let mut file = File::create("data").expect("create failed");
file.write_all(&number.to_ne_bytes()).expect("write failed");
println!("data written to file" );
// read file
let mut file = File::open("data").expect("open failed");
let mut buffer = Vec::<u8>::new();
file.read_to_end(&mut buffer);
//convert binary in vector back a variable of type usize
let mut arr = [0; 8]; //setup an empty array with 8 elements
arr.copy_from_slice(&buffer[0..buffer.len()]); //fill the fixed size array with the slice
let reading_of_number = usize::from_ne_bytes(arr); //convert the array to a variable of type usize
println!("{:?}", reading_of_number);
}
Please note the consequence of using to_ne_bytes() and from_ne_bytes().
If the file is going to be written on one machine, and read on another then you will instead need to use to_be_bytes or to_le_bytes, as appropriate. However, if the file will always be written and read on the same machine, this shouldn't be an issue and you can continue to use to_ne_bytes() and from_ne_bytes() - See docs https://doc.rust-lang.org/std/primitive.u64.html#method.to_ne_bytes
Thanks @user2722968 for suggesting I improve the answer with the importance of understanding be/le/ne.
Upvotes: 4