如何用io::Cursor与byteorder读取混合文件并解析char型文件名
嘿,我来帮你搞定这个file_name字段的解析问题!首先得明确一个关键点:你定义里的char{16}并不是Rust原生的char类型(Rust的char是单个Unicode标量值,占4字节),它应该是指16字节的固定长度字符序列,而且因为文件是非UTF-8格式,我们得用对应编码来解码这些字节。
下面是具体的实现步骤和完整代码示例:
第一步:修正结构体定义
首先把你的结构体改成符合Rust语法的形式,file_name用String存储解码后的字符串,而不是char:
#[derive(Debug)] struct DataParse { file_num: u16, file_name: String, file_size: u32, file_off: u32, file_dum: u8, }
第二步:实现解析逻辑
结合io::Cursor和byteorder,再用encoding_rs库处理非UTF-8编码(你可以根据文件实际编码替换,比如GBK、Shift-JIS、ASCII等):
use byteorder::{LittleEndian, ReadBytesExt}; // 根据文件实际字节序选择LittleEndian/BigEndian use std::io::{Cursor, Read}; use encoding_rs::GBK; // 这里假设文件用GBK编码,替换成你实际的编码即可 fn parse_data_buffer(buffer: &[u8]) -> Result<DataParse, Box<dyn std::error::Error>> { let mut cursor = Cursor::new(buffer); // 读取数值类型字段 let file_num = cursor.read_u16::<LittleEndian>()?; // 读取file_name的16字节缓冲区 let mut name_bytes = [0u8; 16]; cursor.read_exact(&mut name_bytes)?; // 解码非UTF-8字节为字符串 let (decoded_name, _, _) = GBK.decode(&name_bytes); // 去掉字段末尾可能的空终止符(很多二进制文件会用\0填充剩余空间) let file_name = decoded_name.trim_end_matches('\0').to_string(); // 读取剩余字段 let file_size = cursor.read_u32::<LittleEndian>()?; let file_off = cursor.read_u32::<LittleEndian>()?; let file_dum = cursor.read_u8()?; Ok(DataParse { file_num, file_name, file_size, file_off, file_dum, }) }
关键细节说明
- 编码选择:一定要确认文件实际使用的编码(比如ASCII、GB2312、Shift-JIS等),替换代码里的
GBK即可。如果不确定,可以尝试几种常见编码测试。 - 字节序:代码里用了
LittleEndian,如果你的文件是大端序,换成BigEndian就行。 - 空终止符处理:大部分二进制文件的字符串字段会用
\0填充到固定长度,所以解码后要trim_end_matches('\0')去掉无效的空字符。 - 依赖添加:需要在
Cargo.toml里添加这两个依赖:[dependencies] byteorder = "1.4" encoding_rs = "0.8"
内容的提问来源于stack exchange,提问作者ExecAssa
相关产品推荐
相关产品推荐

