QByteArray 详细介绍(1)

QByteArray类是一个字节数组类。

QByteArray 可用于存储原始字节(包括'\0')和传统的 8 位 '\0' 终止字符串。使用 QByteArray 比使用 const char * 方便得多。在后台,它始终确保数据后面跟着 '\0' 终止符,并使用隐式共享(写入时复制)来减少内存使用量并避免不必要的数据复制。

除了QByteArray,Qt还提供了QString类来存储字符串数据。在大多数情况下,QString 是您想要使用的类。它存储 16 位 Unicode 字符,可以轻松地在应用程序中存储non-ASCII/non-Latin-1字符。此外,QString在Qt API中始终使用。QByteArray适合的两个主要情况是,当你需要存储原始二进制数据以及当内存节省是至关重要的时(例如,使用Qt用于嵌入式Linux)。

初始化 QByteArray 的一种方法是简单地将 const char * 传递给其构造函数。例如,以下代码创建一个大小为 5 的字节数组,其中包含数据“Hello”:

QByteArray ba("Hello");

虽然 size() 是 5,但字节数组还在末尾保留一个额外的'\0'字符,这样如果使用一个函数来请求指向底层数据的指针(例如调用 data()),则指向的数据保证以'\0'结尾。

QByteArray 会制作 const char * 数据的深层副本,因此您可以稍后对其进行修改而不会遇到副作用。(如果出于性能原因,您不想创建字符数据的深层副本,请改用 QByteArray::fromRawData()。

另一种方法是使用 resize() 设置数组的大小,并初始化每个字节的数据字节。QByteArray 使用从 0 开始的索引,就像C++数组一样。要访问特定索引位置的字节,可以使用运算符 []()。在非常量字节数组上,operator[]() 返回对可在赋值左侧使用的字节的引用。例如:

QByteArray ba;
ba.resize(5);
ba[0] = 0x3c;
ba[1] = 0xb8;
ba[2] = 0x64;
ba[3] = 0x18;
ba[4] = 0xca;

对于只读访问,另一种语法是使用 at():

for (int i = 0; i < ba.size(); ++i) {
    if (ba.at(i) >= 'a' && ba.at(i) <= 'f')
        cout << "Found character in range [a-f]" << endl;
}

at() 可以比 operator[]() 快,因为它从不会导致发生深层复制。

要一次提取多个字节,请使用 left()、right() 或 mid()。

QByteArray 可以嵌入 '\0' 字节。size() 函数始终返回整个数组的大小,包括嵌入的 '\0' 字节,但不包括 QByteArray 添加的终止 '\0'。例如:

QByteArray ba1("ca\0r\0t");
ba1.size();                     // Returns 2.
ba1.constData();                // Returns "ca" with terminating \0.

QByteArray ba2("ca\0r\0t", 3);
ba2.size();                     // Returns 3.
ba2.constData();                // Returns "ca\0" with terminating \0.

QByteArray ba3("ca\0r\0t", 4);
ba3.size();                     // Returns 4.
ba3.constData();                // Returns "ca\0r" with terminating \0.

const char cart[] = {'c', 'a', '\0', 'r', '\0', 't'};
QByteArray ba4(QByteArray::fromRawData(cart, 6));
ba4.size();                     // Returns 6.
ba4.constData();                // Returns "ca\0r\0t" without terminating \0.

如果要获取数据长度,直到第一个'\0'字符,并排除第一个'\0'字符,请在字节数组上调用 qstrlen()。

调用 resize() 后,新分配的字节具有未定义的值。若要将所有字节设置为特定值,请调用 fill()。

要获取指向实际字符数据的指针,请调用 data() 或 constData()。这些函数返回指向数据开头的指针。指针保证保持有效,直到在 QByteArray 上调用非常量函数。还可以保证数据以'\0'字节结尾,除非 QByteArray 是从原始数据创建的。这个'\0'字节由 QByteArray 自动提供,不计入 size() 中。

QByteArray 提供了以下用于修改字节数据的基本函数:append()、prepend()、insert()、replace() 和 remove()。例如:

QByteArray x("and");
x.prepend("rock ");         // x == "rock and"
x.append(" roll");          // x == "rock and roll"
x.replace(5, 3, "&");       // x == "rock & roll"

replace() 和 remove() 函数的前两个参数是开始擦除的位置和应该擦除的字节数。

当您将数据append() 到非空数组时,该数组将被重新分配,新数据将复制到其中。您可以通过调用 reserve() 来避免此行为,这会预先分配一定量的内存。你也可以调用 capacity() 来找出 QByteArray 实际分配了多少内存。不会复制附加到空数组的数据。

常见的要求是从字节数组中删除空格字符('\n'、'\t'、' '等)。如果要删除 QByteArray 两端的空格,请使用 trimmed() 。如果要删除两端的空格,并将多个连续的空格替换为字节数组中的单个空格字符,请使用 simplified()。

如果要查找 QByteArray 中特定字符或子字符串的所有匹配项,请使用 indexOf() 或 lastIndexOf()。前者从给定的索引位置开始向后搜索,后者向前搜索。如果找到字符或子字符串,两者都返回它的索引位置;否则,它们返回 -1。例如,下面是一个典型的循环,用于查找特定子字符串的所有匹配项:

QByteArray ba("We must be <b>bold</b>, very <b>bold</b>");
int j = 0;
while ((j = ba.indexOf("<b>", j)) != -1) {
    cout << "Found <b> tag at index position " << j << endl;
    ++j;
}

如果您只想检查 QByteArray 是否包含特定字符或子字符串,请使用 contains()。如果要了解特定字符或子字符串在字节数组中出现的次数,请使用 count()。如果要将特定值的所有匹配项替换为另一个值,请使用双参数 replace() 重载之一。

可以使用重载运算符比较 QByteArrays,例如运算符<(),运算符<=(),运算符==(),运算符>=()等。比较完全基于字符的数值,并且非常快,但不是人类所期望的。QString::localeAwareCompare() 是排序用户界面字符串的更好选择。

由于历史原因,QByteArray 区分空字节数组和空字节数组。空字节数组是使用 QByteArray 的默认构造函数或通过向构造函数传递 (const char *)0 来初始化的字节数组。空字节数组是大小为 0 的任何字节数组。空字节数组始终为空,但空字节数组不一定为空:

QByteArray().isNull();          // returns true
QByteArray().isEmpty();         // returns true

QByteArray("").isNull();        // returns false
QByteArray("").isEmpty();       // returns true

QByteArray("abc").isNull();     // returns false
QByteArray("abc").isEmpty();    // returns false

除 isNull() 之外的所有函数都将空字节数组视为空字节数组。例如,data() 返回一个指针,指向空字节数组(不是空指针)的'\0'字符,并且 QByteArray() 比较等于 QByteArray("")。我们建议您始终使用 isEmpty() 并避免使用 isNull()。

注:参考Qt帮助文档

后续公众号会发布系列教程,更多内容请关注公众号:程序猿学习日记

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值