用bincode序列化编写对象后,从文件中读取准确的字节数
我只是在用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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
size_of ::&lt; node&gt;()
是node
的实例在堆栈中占据。它总是恒定的。它等于32,因为字符串
是triple(data_ptr,长度,容量)
(不一定按此顺序),其中每个组件都是usize
- 大小 - 64个位平台上的8个字节,一个u32
-4字节 - 对于eend_ptr
。但是,序列化数据的大小是动态的。它取决于序列化数据,因为它连续序列序列,并且不使用指针。在这种情况下,字符串
node_1
+ ausize
的长度 +u32
用于end_ptr
。如果您没有数据,则无法知道序列化大小。如果确实有数据,则可以调用 。
附带说明,请勿使用
write()
:不能保证写所有数据。使用 而不是。size_of::<Node>()
is the size an instance ofNode
occupies in the stack. It is always constant. It equals 32 sinceString
is a triple(data_ptr, length, capacity)
(not necessarily in this order) where each of the components isusize
-sized - 8 bytes on 64 bit platforms, and oneu32
- 4 bytes - forend_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
+ ausize
for its length +u32
forend_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. Usewrite_all()
instead.