用bincode序列化编写对象后,从文件中读取准确的字节数

发布于 2025-02-09 02:14:59 字数 1410 浏览 2 评论 0原文

我只是在用bincode的文件编写和读取对象来实验。我计划将指针保留到文件中的不同位置,因此我希望能够使用read_exact来阅读这些点。

香港专业教育学院(Ive)写了一些测试,以了解它的工作原理。创建一个结构,将其写入文件,获取结构的大小,然后准确地读取许多字节。

问题是,std :: mem :: size_of返回的对象的大小与写入文件的字节数不同。

这是代码:

use std::fs::{File, OpenOptions};
use std::io::prelude::*;
use bincode::*;
use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize, PartialEq, Debug)]
pub struct Node {

    pub name: String,

    end_ptr: u32 // number of bytes away the next node is
}

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

    let node = Node { name: String::from("node_1"), end_ptr: 0 };

    let node_as_buf = bincode::serialize(&node).unwrap();

    let mut file = OpenOptions::new()
        .read(true)
        .write(true)
        .create(true)
        .truncate(true)
        .open("test.txt")
        .unwrap();

    file.write(&node_as_buf);

    const size_of_node: usize = std::mem::size_of::<Node>();

    println!("{}", file.metadata().unwrap().len()); //  this prints 18

    println!("{}", size_of_node); // and this prints 32, i was expecting them to be the same length

    let mut buffer = [0; size_of_node];

    file.read_exact(&mut buffer[..]).unwrap(); // this says 'failed to fill whole buffer'

    let read_node: Node = bincode::deserialize(&buffer[..]).unwrap();
}

这样做的正确方法是什么?还有其他一些方法可以使我的结构大小吗?

Im just experimenting with writing and reading objects to a file with bincode. I plan to keep pointers to different locations within the file and so I would like to be able to read up to those points with read_exact.

Ive written a little test to see how it would work. Creating a struct, writing it to file, getting the size of the struct and then reading precisely that many bytes.

Issue is that the size of the object returned by std::mem::size_of is not the same as the number of bytes written to the file.

Here is the code:

use std::fs::{File, OpenOptions};
use std::io::prelude::*;
use bincode::*;
use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize, PartialEq, Debug)]
pub struct Node {

    pub name: String,

    end_ptr: u32 // number of bytes away the next node is
}

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

    let node = Node { name: String::from("node_1"), end_ptr: 0 };

    let node_as_buf = bincode::serialize(&node).unwrap();

    let mut file = OpenOptions::new()
        .read(true)
        .write(true)
        .create(true)
        .truncate(true)
        .open("test.txt")
        .unwrap();

    file.write(&node_as_buf);

    const size_of_node: usize = std::mem::size_of::<Node>();

    println!("{}", file.metadata().unwrap().len()); //  this prints 18

    println!("{}", size_of_node); // and this prints 32, i was expecting them to be the same length

    let mut buffer = [0; size_of_node];

    file.read_exact(&mut buffer[..]).unwrap(); // this says 'failed to fill whole buffer'

    let read_node: Node = bincode::deserialize(&buffer[..]).unwrap();
}

What is the proper way to do this? Is there some other way to get the size of my struct?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

沦落红尘 2025-02-16 02:14:59

size_of ::&lt; node&gt;()node的实例在堆栈中占据。它总是恒定的。它等于32,因为字符串是triple (data_ptr,长度,容量)(不一定按此顺序),其中每个组件都是usize - 大小 - 64个位平台上的8个字节,一个u32 -4字节 - 对于eend_ptr

但是,序列化数据的大小是动态的。它取决于序列化数据,因为它连续序列序列,并且不使用指针。在这种情况下,字符串node_1 + a usize的长度 + u32用于end_ptr

如果您没有数据,则无法知道序列化大小。如果确实有数据,则可以调用

附带说明,请勿使用 write() :不能保证写所有数据。使用 而不是。

size_of::<Node>() is the size an instance of Node occupies in the stack. It is always constant. It equals 32 since String is a triple (data_ptr, length, capacity) (not necessarily in this order) where each of the components is usize-sized - 8 bytes on 64 bit platforms, and one u32 - 4 bytes - for end_ptr.

The size of serialized data, however, is dynamic. It depends on the serialized data, since it serializes it contiguously and does not use pointers. In this case, it is 6 bytes for the string node_1 + a usize for its length + u32 for end_ptr.

If you do not have the data you cannot know the serialized size. If you do have the data you can call bincode::serialized_size().

As a side note, do not use write(): it is not guaranteed to write all data. Use write_all() instead.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文