结构体的保存/加载工作或失败取决于成员向量长度

如何解决结构体的保存/加载工作或失败取决于成员向量长度

我使用 serde 和 bincode 使用自定义加载/保存方法定义了以下结构:

use std::{
    fs::File,io::{Read,Seek,SeekFrom,Write},};

use serde::{Deserialize,Serialize};
#[derive(Clone,Debug,Serialize,Deserialize)]
pub struct Histogram {
    pub bars: Vec<f64>,}

#[derive(Clone,Deserialize)]
pub struct Histograms {
    pub num_bars: usize,pub num_histograms: usize,pub vec: Vec<Histogram>,}

fn main() {
    println!("Hello,world!");
}

impl Histogram {
    pub fn new(num_bars: usize) -> Histogram {
        Histogram {
            bars: vec![0.0; num_bars],}
    }
}

impl Histograms {
    pub fn new(num_histograms: usize,num_bars: usize) -> Histograms {
        let histograms = Histograms {
            vec: vec![Histogram::new(num_bars); num_histograms],num_histograms,num_bars,};
        histograms
    }

    pub fn save(&self,filename: &str) {
        let mut file = File::create(format!("{}{}","path",filename)).unwrap();
        let bin = bincode::serialize(&self).unwrap();
        Write::write_all(&mut file,&bin).unwrap();
    }

    pub fn load(filename: &str) -> Histograms {
        let mut file = File::open(format!("{}{}",filename)).unwrap();
        let mut vec: Vec<u8> = vec![0; file.seek(SeekFrom::End(0)).unwrap() as usize];
        file.seek(SeekFrom::Start(0)).unwrap();
        file.read(&mut vec).unwrap();
        let result: Histograms = bincode::deserialize(&vec).unwrap();
        result
    }
}

现在奇怪的是,下面的测试告诉我,如果 vec(直方图的成员)的长度很小,则保存/加载工作正常,但它失败了(我没有收到任何错误,只是结果直方图实例是错误的)具有较大的值,例如 10000000。确切地说,我从它不再正确的地方得到了 5263431 的值。

mod tests {
    use core::panic;

    use super::*;
    #[test]
    fn save_load_test() {
        let histogramms = Histograms::new(10000000,50);
        histogramms.save("debug_test");
        let histogramms1 = Histograms::load("debug_test");
        assert_eq!(histogramms.vec.len(),histogramms1.vec.len());
        let mut Failed = false;
        for i in 0..histogramms.vec.len() {
            if histogramms.vec[i].bars.len() != histogramms1.vec[i].bars.len() {
                Failed = true;
                println!("first i that Failed: {}",i);
                println!(
                    "histogramms.vec.bars.len: {} histogramms1.vec.bars.len: {}",histogramms.vec[i].bars.len(),histogramms1.vec[i].bars.len()
                );
                break;
            }
        }
        if Failed {
            panic!()
        }
    }
}

知道出了什么问题吗?

解决方法

Read::read() 函数从源中提取一些 字节,但不能保证读取所有字节。您得到的唯一保证是,如果还有剩余字节,您将获得 一些 字节(至少如果您的缓冲区的长度不为零)。

解决此问题的最简单方法是改用 std::fs::read() 函数:

pub fn load(filename: &str) -> Histograms {
    let vec = std::fs::read(format!("{}{}","path",filename)).unwrap();
    bincode::deserialize(&vec).unwrap()
}

更好的解决方法是直接从文件中反序列化,而不是先将整个文件读入内存:

pub fn save(&self,filename: &str) {
    let mut w = BufWriter::new(File::create(format!("{}{}",filename)).unwrap());
    bincode::serialize_into(&mut w,&self).unwrap();
    w.flush().unwrap();
}

pub fn load(filename: &str) -> Histograms {
    let file = File::open(format!("{}{}",filename)).unwrap();
    bincode::deserialize_from(BufReader::new(file)).unwrap()
}

(当然,您应该为实际代码添加适当的错误处理。)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?