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() vs operator[])和内存管理(如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,同时正确处理字节序和边界条件。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值