当前位置: 首页 > article >正文

用Rust中byteorder包高效处理字节序列

在 Rust 中,byteorder 是一个用于处理字节序的 crate ,字节序指的是多字节数据类型在内存中的存储顺序,主要分为大端序(Big-Endian)和小端序(Little-Endian)。大端序是将高位字节存于低地址,小端序则相反。byteorder crate 提供了方便的方法来处理不同字节序的数据,在网络编程、文件格式处理等场景中非常有用。以下是一些主要内容和示例:

byteorder 介绍

在 Rust 中,byteorder 是一个用于处理字节序的 crate ,字节序指的是多字节数据类型在内存中的存储顺序,主要分为大端序(Big-Endian)和小端序(Little-Endian)。大端序是将高位字节存于低地址,小端序则相反。byteorder crate 提供了方便的方法来处理不同字节序的数据,在网络编程、文件格式处理等场景中非常有用。以下是一些主要内容和示例:
在这里插入图片描述

主要模块和类型

  • ByteOrder trait:这是 byteorder crate 的核心,定义了用于读写不同字节序数据的方法,所有具体的字节序类型都实现了这个 trait 。
  • BigEndianLittleEndian:这是两个具体的字节序类型,分别对应大端序和小端序,实现了 ByteOrder trait ,提供了如 read_u16write_u32 等一系列方法用于读写不同类型的整数数据。

基本读写示例

在这里插入图片描述

以下是一些使用 byteorder crate 的示例代码:

读取大端序数据

use byteorder::{BigEndian, ByteOrder};

fn main() {
    let buffer: [u8; 4] = [0x12, 0x34, 0x56, 0x78];
    let mut cursor = std::io::Cursor::new(buffer);
    let num = BigEndian::read_u32(&mut cursor);
    println!("Read number in big-endian: {}", num);
}

在这个示例中,通过 BigEndianread_u32 方法从给定的字节数组中读取一个大端序的 32 位整数。

写入小端序数据

use byteorder::{LittleEndian, ByteOrder};
use std::io::Cursor;

fn main() {
    let mut buffer: [u8; 4] = [0; 4];
    let mut cursor = Cursor::new(buffer);
    LittleEndian::write_u32(&mut cursor, 0x78563412);
    println!("Written number in little-endian: {:?}", cursor.into_inner());
}

这里使用 LittleEndianwrite_u32 方法将一个小端序的 32 位整数写入字节数组。

网络数据处理

use byteorder::{BigEndian, ByteOrder};
use std::net::UdpSocket;

fn main() -> std::io::Result<()> {
    let socket = UdpSocket::bind("127.0.0.1:8888")?;
    let mut buffer = [0; 1024];
    let (len, _) = socket.recv_from(&mut buffer)?;
    let num = BigEndian::read_u32(&buffer[..len]);
    println!("Received number in big-endian: {}", num);
    Ok(())
}

此示例展示了在网络编程中,使用 byteorder 来接收和解析大端序的网络数据 ,假设接收的是一个 4 字节的大端序整数。

读写不同数据类型

无符号整数类型

  • read_u8write_u8

    • 功能:用于读写 1 个字节的无符号整数,即u8类型的数据。
    • 示例
    use byteorder::{ByteOrder, LittleEndian};
    use std::io::Cursor;
    
    fn main() {
        let mut buffer: [u8; 1] = [0; 1];
        let mut cursor = Cursor::new(buffer);
        LittleEndian::write_u8(&mut cursor, 255);
        let num = LittleEndian::read_u8(&mut cursor);
        println!("{}", num); 
    }
    
  • read_u16write_u16

    • 功能:用于读写 2 个字节的无符号整数,对应u16类型。
    • 示例
    use byteorder::{ByteOrder, LittleEndian};
    use std::io::Cursor;
    
    fn main() {
        let mut buffer: [u8; 2] = [0; 2];
        let mut cursor = Cursor::new(buffer);
        LittleEndian::write_u16(&mut cursor, 65535);
        let num = LittleEndian::read_u16(&mut cursor);
        println!("{}", num); 
    }
    
  • read_u32write_u32

    • 功能:用于读写 4 个字节的无符号整数,也就是u32类型的数据。
    • 示例
    // 前面已展示过write_u32的示例,这里展示read_u32单独示例
    use byteorder::{ByteOrder, BigEndian};
    use std::io::Cursor;
    
    fn main() {
        let buffer: [u8; 4] = [0x12, 0x34, 0x56, 0x78];
        let mut cursor = Cursor::new(buffer);
        let num = BigEndian::read_u32(&mut cursor);
        println!("{}", num); 
    }
    

有符号整数类型

  • read_i8write_i8

    • 功能:用于读写 1 个字节的有符号整数,即i8类型的数据。
    • 示例
    use byteorder::{ByteOrder, LittleEndian};
    use std::io::Cursor;
    
    fn main() {
        let mut buffer: [u8; 1] = [0; 1];
        let mut cursor = Cursor::new(buffer);
        LittleEndian::write_i8(&mut cursor, -128);
        let num = LittleEndian::read_i8(&mut cursor);
        println!("{}", num); 
    }
    
  • read_i64write_i64

    • 功能:用于读写 8 个字节的有符号整数,对应i64类型。
    • 示例
    use byteorder::{ByteOrder, LittleEndian};
    use std::io::Cursor;
    
    fn main() {
        let mut buffer: [u8; 8] = [0; 8];
        let mut cursor = Cursor::new(buffer);
        LittleEndian::write_i64(&mut cursor, -9223372036854775808);
        let num = LittleEndian::read_i64(&mut cursor);
        println!("{}", num); 
    }
    
  • 浮点数类型

    • read_f32write_f32

      • 功能:用于读写 4 个字节的单精度浮点数,即f32类型的数据。
      • 示例
      use byteorder::{ByteOrder, LittleEndian};
      use std::io::Cursor;
      
      fn main() {
          let mut buffer: [u8; 4] = [0; 4];
          let mut cursor = Cursor::new(buffer);
          LittleEndian::write_f32(&mut cursor, 3.14);
          let num = LittleEndian::read_f32(&mut cursor);
          println!("{}", num); 
      }
      

写文件示例

以下是一个使用 byteorder crate 在 Rust 中写文件并处理字节序的示例。这个示例将创建一个包含不同类型数据(整数、浮点数等)的结构体,然后将该结构体的数据以指定的字节序写入到文件中。

use byteorder::{BigEndian, ByteOrder, WriteBytesExt};
use std::fs::File;
use std::io::{BufWriter, Error, Write};

// 定义一个包含不同类型数据的结构体
#[derive(Debug)]
struct DataToWrite {
    integer_value: u32,
    floating_value: f32,
    another_integer: i16,
}

fn main() -> Result<(), Error> {
    let data = DataToWrite {
        integer_value: 12345,
        floating_value: 3.14,
        another_integer: -50,
    };

    let file_path = "output.bin";
    let file = File::create(file_path)?;
    let mut writer = BufWriter::new(file);

    // 使用BigEndian字节序将数据写入文件
    writer.write_u32::<BigEndian>(data.integer_value)?;
    writer.write_f32::<BigEndian>(data.floating_value)?;
    writer.write_i16::<BigEndian>(data.another_integer)?;

    writer.flush()?;

    println!("Data has been written to {}", file_path);

    Ok(())
}

在上述示例中:

  1. 首先定义了 DataToWrite 结构体,它包含了不同类型的数据,如 u32 类型的整数、f32 类型的浮点数和 i16 类型的有符号整数。
  2. main 函数中,创建了一个 DataToWrite 结构体的实例 data,并指定了要写入文件的数据值。
  3. 然后通过 File::create 创建了一个名为 output.bin 的文件,并使用 BufWriter 对文件写入操作进行缓冲处理,提高写入性能。
  4. 接着,使用 byteorder crate 提供的 write_u32::<BigEndian>write_f32::<BigEndian>write_i16::<BigEndian> 方法,按照大端序(BigEndian)将结构体中的各个数据依次写入到文件中。
  5. 最后,调用 writer.flush() 确保所有缓冲的数据都被真正写入到文件中,并打印出提示信息表示数据已成功写入文件。

http://www.kler.cn/a/402486.html

相关文章:

  • Hive的基础函数-日期函数
  • 《线性代数的本质》
  • 【网络通信】数据集合集!
  • Burp入门(1)
  • C# 读取多条数据记录导出到 Word标签模板之图片输出改造
  • IEC61850读服务器目录命令——GetServerDirectory介绍
  • 第二十二章 Spring之假如让你来写AOP——Target Object(目标对象)篇
  • 项目管理交流会 | 产品研发项目管理主题会议成功举办
  • Cesium 加载B3DM模型
  • 枫清科技亮相 2024 中国 5G+工业互联网大会,推动 AI 赋能新型工业化
  • Spring Boot教程之四:在IntelliJ IDEA 以及 Eclips IDE中创建和配置Spring Boot
  • 根据条件 控制layui的table的toolbar的按钮 显示和不显示
  • 【Redis】实现点赞功能
  • 5.tree of thought 源码 (prompts 类)
  • 零基础入门Flink,掌握基本使用方法
  • 华为openEuler考试真题演练(附答案)
  • # TCP、UDP、HTTP、Socket
  • 无人机CAN总线基础——CKESC电调小课堂14
  • 平价鼠标推荐-英菲克PW1有线鼠标
  • 【Spring boot】微服务项目的搭建整合swagger的fastdfs和demo的编写
  • Linux中定时操作
  • 【AIGC】破解ChatGPT!如何使用高价值提示词Prompt提升响应质量
  • 109. UE5 GAS RPG 实现检查点的存档功能
  • 计算机毕业设计Hive+Spark空气质量预测 空气质量可视化 空气质量分析 空气质量爬虫 Hadoop 机器学习 深度学习 Django 大模型
  • 鱼厂实习,光速转正了!
  • 【STM32项目】基于STM32设计的震动马达超声波电机高频震动——高级定时器PWM互补输出带死区控制