You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:12:48