问题描述
说我有一个带有分支的大型结构,例如以下示例:
use serde_derive::{Serialize,Deserialize};
use bincode;
use std::fs::File;
use std::io::prelude::*;
use std::io::SeekFrom;
#[derive(Serialize)]
pub struct A {
pub field0: u32,pub field1: Vec<B>
}
#[derive(Serialize)]
pub struct B {
pub field0: u32,pub field1: Cenum,pub field2: Vec<C>
}
#[derive(Serialize,Deserialize,Debug)]
pub struct C {
pub field: Vec<u8>
}
#[derive(Serialize)]
pub enum Cenum {
Q,W
}
fn main() {
let myvec_len3: Vec<u8> = vec![0xA5,0xA5,0xA5];
let myvec_len4: Vec<u8> = vec![0xE2,0xE2,0xE2];
let foo = A {
field0: 0xF0F0F0F0,field1: vec![
B { field0: 0xA0A0A0A0,field1: Cenum::Q,field2: vec![
C { field: myvec_len3.clone() },C { field: myvec_len4.clone() }]},// VALUE WE WANT
B { field0: 0xF2F2F2F2,field1: Cenum::W,C { field: myvec_len4.clone() },C { field: myvec_len3.clone() }]}]};
let bytes = bincode::serialize(&foo).unwrap();
let mut f = File::create("byte_dump").unwrap();
f.write_all(&bytes[..] as &[u8]).expect("Failed to write to file.");
}
该程序将序列化填充有值的结构foo
并以二进制形式写入文件。如果我使用Linux命令byte_dump
十六进制转储输出文件xxd
,则输出为:
00000000: f0f0 f0f0 0200 0000 0000 0000 a0a0 a0a0 ................
00000010: 0000 0000 0200 0000 0000 0000 0300 0000 ................
00000020: 0000 0000 a5a5 a504 0000 0000 0000 00e2 ................
00000030: e2e2 e2f2 f2f2 f201 0000 0003 0000 0000 ................
00000040: 0000 0003 0000 0000 0000 00a5 a5a5 0400 ................
00000050: 0000 0000 0000 e2e2 e2e2 0300 0000 0000 ................
00000060: 0000 a5a5 a5 .....
希望通过这种方式可以轻松地看到不同的成员值(例如foo.field0
是前8个符号f0f0 f0f0
,相当于其十六进制值)。
现在说我们要从foo.field1[0].field2[1].field
文件中获取byte_dump
(标记为VALUE WE WANT注释)。从十六进制转储,我们知道此结构C位于第一个0x27
序列之后的字节a5a5 a5
上,并在字节f2 f2f2 f2
的{{1}}之前结束。总的来说,这是12个字节,其中0x33
是矢量值,04 0000 0000 0000 00
是我们的值。
要反序列化此序列,请在e2 e2e2 e2
的末尾附加以下代码:
main()
现在,编译后,希望函数输出 // main() {
// -snipped-
let mut f = File::open("byte_dump").unwrap();
f.seek(SeekFrom::Start(0x27)).unwrap(); // Set current byte to 0x27
const BR: usize = 12; // bytes to read
let mut bytes: [u8; BR] = [0; BR]; // init buffer
f.take(BR as u64).read(&mut bytes).unwrap(); // read 12 bytes from current byte
let bar: C = bincode::deserialize(&bytes).unwrap();
assert_eq!(bar.field,foo.field1[0].field2[1].field);
println!("{:X?}",bar.field); // Success!
}
。
问题:
在此示例中,我使用了[E2,E2,E2]
和serde
板条箱来bincode
结构的反序列化。但是现在我想使代码自动化,该代码在更大得多的文件中为结构C的每个实例创建一个排序的字节偏移量表,该文件具有更多嵌套的结构成员。为此,在将序列化的foo
写入文件时,我需要存储当前字节和字节以读取每个结构C实例。
现在foo
中有自定义(反)序列化功能的功能,但是我不知道要使用哪种算法,如何开始编写它,或者甚至可以用{{1 }}。如何将序列化的结构逐个成员写入文件?写完后如何知道我当前在哪个字节上?如何仅将要读取的文件的一部分加载到内存中?这么多的问题。所以我问这里是否有人有经验或专业知识可以帮助我。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)