字节序操作byteorder 字节数组操作是一个高频的操作,rust生态中有bytes和byteorder两个第三方库来处理。两个库的操作方法基本类似,我们选择byteorder来做介绍。 在byteorder中定义了BigEndian和LittleEndian两个枚举类,这两个枚举类分别实现了byteorder::ByteOrder个trait。 byteorder::ByteOrder提供发了丰富的接口来实现常用类型转成字节数组。pubtraitByteOrder:CloneCopyDebugDefaultEqHashOrdPartialEqPartialOrdSealed{fnreadu16(buf:〔u8〕)u16;fnreadu32(buf:〔u8〕)u32;fnreadu64(buf:〔u8〕)u64;fnreadu128(buf:〔u8〕)u128;fnreaduint(buf:〔u8〕,nbytes:usize)u64;fnreaduint128(buf:〔u8〕,nbytes:usize)u128;fnwriteu16(buf:mut〔u8〕,n:u16);fnwriteu32(buf:mut〔u8〕,n:u32);fnwriteu64(buf:mut〔u8〕,n:u64);fnwriteu128(buf:mut〔u8〕,n:u128);fnwriteuint(buf:mut〔u8〕,n:u64,nbytes:usize);fnwriteuint128(buf:mut〔u8〕,n:u128,nbytes:usize);fnreadu16into(src:〔u8〕,dst:mut〔u16〕);fnreadu32into(src:〔u8〕,dst:mut〔u32〕);fnreadu64into(src:〔u8〕,dst:mut〔u64〕);fnreadu128into(src:〔u8〕,dst:mut〔u128〕);fnwriteu16into(src:〔u16〕,dst:mut〔u8〕);fnwriteu32into(src:〔u32〕,dst:mut〔u8〕);fnwriteu64into(src:〔u64〕,dst:mut〔u8〕);fnwriteu128into(src:〔u128〕,dst:mut〔u8〕);fnfromsliceu16(numbers:mut〔u16〕);fnfromsliceu32(numbers:mut〔u32〕);fnfromsliceu64(numbers:mut〔u64〕);fnfromsliceu128(numbers:mut〔u128〕);fnfromslicef32(numbers:mut〔f32〕);fnfromslicef64(numbers:mut〔f64〕);fnreadu24(buf:〔u8〕)u32{。。。}fnreadu48(buf:〔u8〕)u64{。。。}fnwriteu24(buf:mut〔u8〕,n:u32){。。。}fnwriteu48(buf:mut〔u8〕,n:u64){。。。}fnreadi16(buf:〔u8〕)i16{。。。}fnreadi24(buf:〔u8〕)i32{。。。}fnreadi32(buf:〔u8〕)i32{。。。}fnreadi48(buf:〔u8〕)i64{。。。}fnreadi64(buf:〔u8〕)i64{。。。}fnreadi128(buf:〔u8〕)i128{。。。}fnreadint(buf:〔u8〕,nbytes:usize)i64{。。。}fnreadint128(buf:〔u8〕,nbytes:usize)i128{。。。}fnreadf32(buf:〔u8〕)f32{。。。}fnreadf64(buf:〔u8〕)f64{。。。}fnwritei16(buf:mut〔u8〕,n:i16){。。。}fnwritei24(buf:mut〔u8〕,n:i32){。。。}fnwritei32(buf:mut〔u8〕,n:i32){。。。}fnwritei48(buf:mut〔u8〕,n:i64){。。。}fnwritei64(buf:mut〔u8〕,n:i64){。。。}fnwritei128(buf:mut〔u8〕,n:i128){。。。}fnwriteint(buf:mut〔u8〕,n:i64,nbytes:usize){。。。}fnwriteint128(buf:mut〔u8〕,n:i128,nbytes:usize){。。。}fnwritef32(buf:mut〔u8〕,n:f32){。。。}fnwritef64(buf:mut〔u8〕,n:f64){。。。}fnreadi16into(src:〔u8〕,dst:mut〔i16〕){。。。}fnreadi32into(src:〔u8〕,dst:mut〔i32〕){。。。}fnreadi64into(src:〔u8〕,dst:mut〔i64〕){。。。}fnreadi128into(src:〔u8〕,dst:mut〔i128〕){。。。}fnreadf32into(src:〔u8〕,dst:mut〔f32〕){。。。}fnreadf32intounchecked(src:〔u8〕,dst:mut〔f32〕){。。。}fnreadf64into(src:〔u8〕,dst:mut〔f64〕){。。。}fnreadf64intounchecked(src:〔u8〕,dst:mut〔f64〕){。。。}fnwritei8into(src:〔i8〕,dst:mut〔u8〕){。。。}fnwritei16into(src:〔i16〕,dst:mut〔u8〕){。。。}fnwritei32into(src:〔i32〕,dst:mut〔u8〕){。。。}fnwritei64into(src:〔i64〕,dst:mut〔u8〕){。。。}fnwritei128into(src:〔i128〕,dst:mut〔u8〕){。。。}fnwritef32into(src:〔f32〕,dst:mut〔u8〕){。。。}fnwritef64into(src:〔f64〕,dst:mut〔u8〕){。。。}fnfromslicei16(src:mut〔i16〕){。。。}fnfromslicei32(src:mut〔i32〕){。。。}fnfromslicei64(src:mut〔i64〕){。。。}fnfromslicei128(src:mut〔i128〕){。。。}}usebyteorder::{ByteOrder,LittleEndian};letmutbuf〔0;4〕;LittleEndian::writeu32(mutbuf,1000000);asserteq!(1000000,LittleEndian::readu32(buf));usebyteorder::{ByteOrder,BigEndian};letmutbuf〔0;2〕;BigEndian::writei16(mutbuf,5000);asserteq!(5000,BigEndian::readi16(buf));usebyteorder::{ByteOrder,BigEndian};letmutnumbers〔5,65000〕;BigEndian::fromslicei64(mutnumbers);asserteq!(numbers,〔5i64。tobe(),65000i64。tobe()〕); 选择byteorder的另一个重要原因是,byteorder定义了另外两个ReadBytesExt和WriteBytesExttrait, ReadBytesExt继承了std::io::Readtrait,然后所有实现std::io::Read的类,将免费获取ReadBytesExt。WriteBytesExt继承了std::io::Writetrait,然后所有实现std::io::Write的类,将免费获取WriteBytesExt。usestd::io::Cusebyteorder::{BigEndian,ReadBytesExt};letmutrdrCursor::new(vec!〔2,5,3,0〕);Cursor〔u8〕实现了std::io::Read所有免费实现了ReadBytesExtasserteq!(517,rdr。readu16::BigEndian()。unwrap());asserteq!(768,rdr。readu16::BigEndian()。unwrap());usestd::f32;usestd::io::Cusebyteorder::{BigEndian,ReadBytesExt};letmutrdrCursor::new(vec!〔0x40,0x49,0x0f,0xdb,0x3f,0x80,0x00,0x00,〕);letmutdst〔0。0;2〕;rdr。readf32into::BigEndian(mutdst)。unwrap();读取float32数组asserteq!(〔f32::consts::PI,1。0〕,dst);usebyteorder::WriteBytesEletmutwtrVec::new();Vec〔u8〕实现了std::io::Write免费实现了WriteBytesExtwtr。writeu8(2)。unwrap();wtr。writeu8(5)。unwrap();asserteq!(wtr,b);自己实现序列化和反序列化struct〔derive(Debug)〕pubstructPerson{features:HashMapi8,Vecf32,featuresize:u16,channelbit:u64,}implPerson{fnsize(self)usize{letlengthself。features。len();iflength1{return7}128(1self。featuresizeasusize4)length}pubfnmarshal(self)OptionVecu8{ifself。size()11{returnNone}letmutbufVec::withcapacity(self。size());buf。writeu8(self。features。len()asu8);buf。writeu16::LittleEndian(self。featuresize);buf。writeu64::LittleEndian(self。channelbit);for(k,v)inself。features{buf。writeu8(kasu8);unsafe{letbstd::slice::fromrawparts(v。asptr()asconstu8,v。len()4);buf。writeall(b);writeall方法来着std::io::Writetrait}}Some(buf)}pubfnunmarshal(mutself,b:〔u8〕)std::result::Result(),std::io::Error{ifb。len()11{returnErr(std::io::Error::new(std::io::ErrorKind::Other,toshort))}letmutrdrCursor::new(b);letlengthrdr。readu8()?;self。featuresizerdr。readu16::LittleEndian()?;self。channelbitrdr。readu64::LittleEndian()?;forin0。。length{letkeyrdr。readu8()?;letmutfeaturevec!〔0。0;self。featuresizeasusize〕;rdr。readf32into::LittleEndian(mutfeature)?;self。features。insert(keyasi8,feature);}Ok(())}}fnmain(){letmutfeaturesHashMap::new();features。insert(1i8,Vec::from(〔2。9;2048〕));features。insert(2i8,Vec::from(〔2。9;2048〕));letpersonPerson{features,featuresize:2048,channelbit:0};letbytesperson。marshal()。unwrap();letmutpersonbPerson{features:HashMap::new(),featuresize:2048,channelbit:0};personb。unmarshal(bytes)。unwrap();println!({:?},person);println!({:?},personb);asserteq!(person。features。get(1)。unwrap(),personb。features。get(1)。unwrap())}