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"
注意事项
- 索引从0开始:QByteArray的索引与C/C++数组一致,
索引0对应第一个字节。 - 长度验证:操作前建议检查长度,避免越界:
cpp1if (byteArray.size() >= 2) { 2 // 安全操作 3} else { 4 // 处理长度不足的情况 5} - 字节序问题:若涉及多字节数值(如
int16),需注意系统字节序(大端/小端),可用qFromBigEndian或qFromLittleEndian转换。
通过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):高位字节在前(如网络传输标准)
cpp1uint16_t usort_big = qFromBigEndian<uint16_t>(byteArray.constData()); - 小端序(Little-Endian):低位字节在前(如x86系统)
cpp1uint16_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();
}
关键说明
- 字节序选择:
- 使用
qFromLittleEndian或qFromBigEndian明确指定字节序,避免系统依赖性。 - 常见场景:网络传输用大端序,本地处理用系统默认序。
- 使用
- 安全性:
- 始终检查
QByteArray长度,防止越界访问。 - 优先使用
constData()而非data()获取只读指针,避免意外修改。
- 始终检查
- 类型匹配:
usort应为uint16_t等精确宽度的整数类型,避免隐式转换错误。
- 十六进制输出:
- 使用
QString::number(value, 16)格式化为十六进制字符串,便于调试。
- 使用
通过上述方法,可安全高效地将QByteArray前两个字节转换为数值并赋值给usort,同时正确处理字节序和边界条件。
2707

被折叠的 条评论
为什么被折叠?



