9716278
9716278

Reputation: 2404

How to write binary number to file and retrieve it in rust

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

Answers (1)

craigmayhew
craigmayhew

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

Related Questions