Can't restore data after I've saved to file

I am struggling with writing and reading data from files. I have a large program with a number of Vectors which are storing Structs. I have written a small example of what I'm trying to do. I cannot seem to find a good example of what I need to do in order to read the file I previously wrote and put the data back into a Vector of Structs.

extern crate serde;
use serde::{Serialize, Deserialize};
use std::io;
use std::io::prelude::*;
extern crate bincode;
use std::fs::File;
use bincode::serialize_into;
use bincode::deserialize_from;
use std::io::BufWriter;
use std::io::BufReader;

#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, Default)]
pub struct Noddy
    name: String,
    number: i32,

fn main()
    let mut noddy_vector = vec![];
    let mut read_noddy_vector= vec![];
    let mut PL = "";
    for a in 1..5
        PL = "Player {}", a ;
        noddy_vector.push(Noddy::Noddy::new( PL, a));

            // Try to save the data! (Appears to work)
        let noddy_vector_encoded = bincode::serialize(&noddy_vector).unwrap();
        let mut f = BufWriter::new(File::create("noddy.dat").unwrap());
        serialize_into(&mut f, &noddy_vector_encoded).unwrap();
            // Try to read the data!
        let mut buf_stream_reader = BufReader::new(File::open("noddy.dat").unwrap());
        let mut x = buf_stream_reader.read_to_end(&mut read_noddy_vector).unwrap();
        let mut cursor = &read_noddy_vector[..];
        println!("{}", cursor[0].name); // I realize this is problematic, but didn't want to implement a "display_noddy" function for this small example.

deserialize_from returns your deserialized values.

let noddy_vector: Vec<Noddy> = deserialize_from(cursor).unwrap();

However, you're serializing the vector twice before saving, which will probably mess up your deserialization. It should look more like

let mut f = BufWriter::new(File::create("noddy.dat").unwrap());
serialize_into(&mut f, &noddy_vector).unwrap();

Also, you should be able to call deserialize_from directly on the BufReader you create instead of having to do read_to_end.

Great thanks. So more like this on the read?

let mut x = deserialize_from(BufReader::new(File::open("noddy.dat").unwrap())).unwrap();
println!("{}", x[0].name);

Yes, but you do have to indicate the type of x, since it could potentially deserialize into multiple different things (you can either do this by annotating the type, or using the variable in some way so type inference can figure its type out correctly.

OK, I used all your suggestions in the actual code, and it does save the data correctly, it attempts to read the data but I get an error of "Failed to fill whole buffer". The backtrace shows, what looks like a problem with the unwrapping.
core::result::Result<alloc::vec::Vec<bigbang::Sector::Sector>, alloc::boxed::Box<bincode::error::ErrorKind>>::unwrap<alloc::vec::Vec<bigbang::Sector::Sector>,alloc::boxed::Box<bincode::error::ErrorKind>>

The code I'm running (from actual program not the Noody example):

// Try to read the data!

let mut read_sector_vector: Vec<Sector::Sector> = deserialize_from(BufReader::new(File::open("sector.dat").unwrap())).unwrap();

Just an note for anyone who might look at this question in the future. The reason I couldn't read the data immediately afterward was because the open file was still in scope. So as soon as I used drop() I could read the data easily.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.