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

QByteArray 常用接口

1.QByteArray 常用接口

QByteArray是Qt框架中用于处理原始字节数据的核心类,其常用接口可分为以下几类,涵盖构造、访问、修改、转换等操作:

1. 构造与初始化

  • 构造函数
    QByteArray(): 创建空字节数组。
    QByteArray(int size, char c): 创建大小为size、每个字节为c的数组。
    QByteArray(const char *str): 从C风格字符串构造(自动计算长度)。
    QByteArray(const QByteArray &other): 拷贝构造。

  • 静态工厂方法
    fromRawData(const char *data, int size): 创建浅拷贝(不复制数据,仅引用)。
    fromStdString(const std::string &str): 从std::string转换。
    fromBase64(const QByteArray &base64): 解码Base64数据。
    fromHex(const QByteArray &hex): 解码十六进制字符串。

2. 数据访问与属性

  • 基本属性
    size() / length(): 返回字节数组长度。
    isEmpty(): 判断是否为空。
    capacity(): 返回当前分配的内存大小(与size()不同)。

  • 元素访问
    at(int i): 返回第i个字节(带边界检查)。
    operator[](int i): 类似at(),但无边界检查(更快)。
    data() / constData(): 返回底层char*指针(可修改/只读)。
    constFirst() / constLast(): 返回首/尾字节(Qt 5.10+)。

3. 内容修改

  • 追加/插入
    append(char c) / append(const char *str): 在末尾添加数据。
    prepend(char c) / prepend(const char *str): 在开头添加数据。
    insert(int i, char c): 在位置i插入字符。

  • 删除与替换
    remove(int pos, int len): 删除从pos开始的len个字节。
    replace(int pos, int len, const char *after): 替换子数组。
    chop(int len): 删除末尾len个字节。
    clear(): 清空数组。

  • 调整内存
    squeeze(): 释放未使用的内存(减少容量至实际大小)。
    reserve(int size): 预分配内存(避免多次重新分配)。
    resize(int size): 调整大小(不足时填充\0,过大时截断)。

4. 字符串转换

  • 与QString互转
    QString toUtf8() const: 转换为UTF-8编码的QString。
    QString fromUtf8(const QByteArray &ba): 静态方法,从UTF-8字节数组创建QString。
    类似接口:toLatin1(),toStdString(),fromStdString()

  • 编码处理
    toHex(): 转换为十六进制字符串(如"A1B2")。
    toBase64(): 编码为Base64。
    setRawData(): 标记数组为原始数据(需手动管理内存)。

5. 查找与比较

  • 查找操作
    indexOf(const QByteArray &ba, int from = 0): 查找子数组位置。
    lastIndexOf(...): 从末尾开始查找。
    contains(const QByteArray &ba): 判断是否包含子数组。
    startsWith(...) / endsWith(...): 检查前缀/后缀。

  • 比较操作
    operator== / != / < / <= / > / >=: 按字典序比较。
    null(): 判断是否为空(与isEmpty()不同,null()表示未分配内存)。

6. 其他实用方法

  • 子数组提取
    mid(int pos, int len = -1): 返回从pos开始、长度为len的子数组(len=-1表示到末尾)。
    left(int len) / right(int len): 返回左/右len个字节。

  • 数值转换
    toInt() / toLong() / toLongLong() / toFloat() / toDouble(): 将字节数组解析为数值(如"123"123)。
    number(int n): 将整数转换为字符串形式(如QByteArray::number(123)"123")。

使用示例

cpp

QByteArray data = "Hello"; data.append(" World"); // 变为"Hello World" data.replace(5, 1, ", "); // 变为"Hello, World" bool found = data.contains("World"); // true QString str = QString::fromUtf8(data); // 转换为QString

这些接口覆盖了QByteArray的常见操作场景,如二进制数据处理、字符串转换、内存管理等。具体使用时需注意边界检查(如at()vsoperator[])和内存管理(如squeeze()减少内存占用)。

2.QByteArray 获取第1个位置的两个字节

在QByteArray中获取第1个位置(索引0)的两个字节,可通过以下两种方式实现,核心逻辑是提取从索引0开始、长度为2的子数组

方法1:使用mid()方法(推荐)

cpp

1QByteArray byteArray = ...; // 假设已初始化 2QByteArray firstTwoBytes = byteArray.mid(0, 2); // 从索引0开始取2个字节
  • 特点:返回新的QByteArray对象,安全且易用。
  • 边界检查:若数组长度不足2,mid()会返回实际可用的字节(如长度不足时返回空数组或部分数据)。

方法2:直接访问底层指针

cpp

1QByteArray byteArray = ...; 2const char* data = byteArray.constData(); // 获取只读指针 3char firstByte = data[0]; // 第0个字节 4char secondByte = data[1]; // 第1个字节
  • 特点:直接操作内存,效率高,但需手动管理边界。
  • 风险:需确保byteArray长度≥2,否则会越界访问导致崩溃。

示例代码

cpp

1QByteArray data = "\x01\x02\x03\x04"; // 二进制数据:01 02 03 04 2 3// 方法1:提取子数组 4QByteArray result = data.mid(0, 2); 5qDebug() << result.toHex(); // 输出 "0102" 6 7// 方法2:直接访问 8qDebug() << QString("%1 %2") 9 .arg(static_cast<int>(data[0]), 2, 16) 10 .arg(static_cast<int>(data[1]), 2, 16); // 输出 "01 02"

注意事项

  1. 索引从0开始:QByteArray的索引与C/C++数组一致,索引0对应第一个字节。
  2. 长度验证:操作前建议检查长度,避免越界:

    cpp

    1if (byteArray.size() >= 2) { 2 // 安全操作 3} else { 4 // 处理长度不足的情况 5}
  3. 字节序问题:若涉及多字节数值(如int16),需注意系统字节序(大端/小端),可用qFromBigEndianqFromLittleEndian转换。

通过mid()方法可安全高效地完成需求,推荐优先使用。

3.把QByteArray的前两个字节读给usort

要将QByteArray的前两个字节读取为一个数值(如uint16_t类型)并赋值给变量usort,需完成以下步骤,核心逻辑包括提取字节数据、处理字节序、类型转换

1. 基础实现(假设小端序)

cpp

1#include <QByteArray> 2#include <cstdint> // 用于uint16_t 3 4QByteArray byteArray = "\x01\x02"; // 示例数据:0x01 0x02 5 6// 检查长度是否足够 7if (byteArray.size() >= 2) { 8 // 方法1:通过底层指针直接读取(小端序) 9 const char* data = byteArray.constData(); 10 uint16_t usort = *reinterpret_cast<const uint16_t*>(data); // 直接组合为16位整数 11 12 // 方法2:使用Qt内置字节序转换(更安全) 13 uint16_t usort_qt = qFromLittleEndian<uint16_t>(byteArray.left(2).constData()); 14}

2. 处理字节序问题

  • 大端序(Big-Endian):高位字节在前(如网络传输标准)

    cpp

    1uint16_t usort_big = qFromBigEndian<uint16_t>(byteArray.constData());
  • 小端序(Little-Endian):低位字节在前(如x86系统)

    cpp

    1uint16_t usort_little = qFromLittleEndian<uint16_t>(byteArray.constData());

3. 完整示例代码

cpp

#include <QCoreApplication> #include <QDebug> #include <cstdint> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // 构造测试数据:0x12 0x34(小端序表示为0x3412) QByteArray data = QByteArray::fromHex("1234"); // 检查长度 if (data.size() < 2) { qDebug() << "Error: Data too short!"; return -1; } // 方法1:直接指针转换(系统依赖字节序) uint16_t usort_raw = *reinterpret_cast<const uint16_t*>(data.constData()); qDebug() << "Raw value (system-endian):" << QString::number(usort_raw, 16); // 方法2:显式指定小端序 uint16_t usort_little = qFromLittleEndian<uint16_t>(data.constData()); qDebug() << "Little-endian value:" << QString::number(usort_little, 16); // 输出 0x3412 // 方法3:显式指定大端序 uint16_t usort_big = qFromBigEndian<uint16_t>(data.constData()); qDebug() << "Big-endian value:" << QString::number(usort_big, 16); // 输出 0x1234 return a.exec(); }

关键说明

  1. 字节序选择
    • 使用qFromLittleEndianqFromBigEndian明确指定字节序,避免系统依赖性。
    • 常见场景:网络传输用大端序,本地处理用系统默认序。
  2. 安全性
    • 始终检查QByteArray长度,防止越界访问。
    • 优先使用constData()而非data()获取只读指针,避免意外修改。
  3. 类型匹配
    • usort应为uint16_t等精确宽度的整数类型,避免隐式转换错误。
  4. 十六进制输出
    • 使用QString::number(value, 16)格式化为十六进制字符串,便于调试。

通过上述方法,可安全高效地将QByteArray前两个字节转换为数值并赋值给usort,同时正确处理字节序和边界条件。

http://www.jsqmd.com/news/101803/

相关文章:

  • 关于JxBrowser 里 Chrome 自带的 PDF 工具栏,能不能隐藏问题?
  • 物流异常通知:LobeChat自动生成安抚话术
  • 基于Java Swing的排序算法可视化器(2)
  • 科研绘图中的色卡选择与高级 Colorbar 设计
  • 基于Java Swing的排序算法可视化器(1)
  • 大语言模型(LLM)学习秘籍:从初学者到专家的必经之路,数学基础与工程实战全解析!
  • RAG聊天机器人终极优化指南
  • Git撤销修改:git restore . 与 git reset --hard 万字详解
  • LobeChat + GPU算力 高效私有化部署AI聊天系统
  • 电子邮件营销模板:LobeChat编写个性化正文
  • mybatis-动态sql语句-<foreach>
  • Leetcode刷题日记15(141-150)
  • LobeChat文件上传功能详解:图文混合输入不再是难题
  • Leetcode刷题日记16(151-160)
  • 本周GitHub九大神级项目推荐,轻松入门大模型技术,错过就是遗憾!
  • Leetcode刷题日记17(161-170)
  • TensorFlow调试报错看不懂?LobeChat帮你解读
  • Leetcode刷题日记18(171-180)
  • LobeChat研究方向建议生成AI
  • 基于PLC控制的四路抢答器设计
  • 【Java SE 基础学习打卡】25 循环结构 - for
  • 2025年度最佳远控软件评选:十佳品牌出炉,国产软件居多!
  • 自动化测试:Java+Selenium自动化测试环境搭建
  • LobeChat百度收录加速方法
  • 软件测试基础知识最强总结
  • python爬虫学习(搜索)
  • DownKyi终极指南:5步掌握B站视频批量下载技巧
  • python的fastapi+uvicorn的linux离线部署
  • 9、循环迭代与函数构建:脚本编程的核心技巧
  • LobeChat与IPFS结合实现去中心化聊天存档