QT常用类型字节数组QByteArray及其基本使用

概述

QByteArray 是 Qt 框架中用于存储字节数组的类,它提供了一系列操作字节数组的函数,非常方便。在 Qt 中,QByteArray 类被广泛用于处理二进制数据、图像、音频、视频等多媒体数据,也可以用于网络传输和文件操作等场景。

特点

QByteArray 的主要特点有:

高效性:QByteArray 的内部实现使用了指针和引用计数技术,可以高效地存储和访问大量数据。
功能强大:QByteArray 提供了丰富的字节数组操作函数,例如 append、insert、replace、remove 等,可以灵活地操作字节数组。
支持多种编码方式:QByteArray 支持多种编码方式,例如 ASCII、UTF-8、UTF-16 等,可以方便地处理不同编码的数据。

常见函数

下面是一些常用的 QByteArray 函数:

QByteArray::append:

将一个字节数组添加到另一个字节数组末尾。

QByteArray byteArray1("hello");
QByteArray byteArray2("world");
byteArray1.append(byteArray2); // 字节数组变为 "helloworld"

QByteArray::insert:

在指定位置插入一个字节数组。

QByteArray byteArray("hello");
byteArray.insert(1, "w"); // 字节数组变为 "hwello"

QByteArray::replace:

替换指定位置的字节数组。

QByteArray byteArray("hello");
byteArray.replace(1, 2, "a"); // 字节数组变为 "hallo"

QByteArray::remove:

移除指定位置的字节数组。

QByteArray byteArray("hello");
byteArray.remove(1, 2); // 字节数组变为 "ho"

QByteArray::toHex:

将字节数组转换为十六进制字符串。

QByteArray byteArray("\x12\x34\x56\x78");
QString hexString = byteArray.toHex(); // hexString = "12345678"

QByteArray::fromHex:

将十六进制字符串转换为字节数组。

QString hexString("12345678");
QByteArray byteArray = QByteArray::fromHex(hexString.toUtf8()); // byteArray = "\x12\x34\x56\x78"

QByteArray::toBase64:

将字节数组转换为 Base64 编码的字符串。

QByteArray byteArray("hello");
QString base64String = byteArray.toBase64(); // base64String = "aGVsbG8="

QByteArray::fromBase64:

将 Base64 编码的字符串转换为字节数组。

QString base64String("aGVsbG8=");
QByteArray byteArray = QByteArray::fromBase64(base64String.toUtf8()); // byteArray = "hello"

注意:灵活使用赋值与QByteArray::detach()

使用 QByteArray 处理字节数组非常方便,可以大大简化代码。但需要注意的是,由于 QByteArray 的内部实现采用指针和引用计数技术,因此当一个 QByteArray 对象被赋值给另一个对象时,实际上只是复制了一个指针,而不是复制整个字节数组。这意味着如果在一个 QByteArray 对象上进行修改,可能会影响到其他使用同一字节数组的对象。

例如,下面的代码创建了两个 QByteArray 对象,它们共享同一个内部字节数组:

QByteArray byteArray1("hello");
QByteArray byteArray2 = byteArray1; // 复制了一个指针
byteArray1[1] = 'a';
qDebug() << byteArray1; // 输出 "hallo"
qDebug() << byteArray2; // 也输出 "hallo"

为了避免这种问题,可以使用 QByteArray::detach() 函数将一个 QByteArray 对象的内部字节数组复制一份,这样就不会影响其他对象了。例如:

QByteArray byteArray1("hello");
QByteArray byteArray2 = byteArray1; // 复制了一个指针
byteArray1.detach(); // 复制字节数组
byteArray1[1] = 'a';
qDebug() << byteArray1; // 输出 "hallo"
qDebug() << byteArray2; // 输出 "hello"

除了上面介绍的函数,QByteArray 还提供了一些其他常用的函数,例如:

QByteArray::size:返回字节数组的大小。
QByteArray::isEmpty:判断字节数组是否为空。
QByteArray::isNull:判断字节数组是否为 null。
QByteArray::clear:清空字节数组。
QByteArray::constData:返回一个指向字节数组数据的常量指针。
QByteArray::data:返回一个指向字节数组数据的非常量指针。
QByteArray::operator[]:通过下标访问字节数组中的某个元素。

小例子:使用QByteArray 接收图片数据并且统计帧率并显示

QByteArray aRecvData = m_pSocket->readAll();/*读取服务器发送的数据*/
    m_aRecvBuffer.append(aRecvData);
    
    QByteArray startMarker = QByteArray::fromHex("FFD8");// 搜索JPEG图像的开始和结束标记*/
    QByteArray endMarker = QByteArray::fromHex("FFD9");
    int nStartIndex = m_aRecvBuffer.indexOf(startMarker);
    int nEndIndex = m_aRecvBuffer.indexOf(endMarker, nStartIndex + startMarker.size());
    /* 如果找到JPEG图像的开始和结束标记*/
    if ( nStartIndex != -1 && nEndIndex != -1) {
        m_nFrameCount++;
        if (m_nFrameCount % 10 == 0) { /* 每10帧输出一次帧率*/
            qint64 elapsed = m_frameTimer.elapsed();
            double dFps = 10000.0 / elapsed; /* 每秒10帧*/
            QString sFpsStr = QString::number(dFps, 'f', 1);  /* 将fps转换为字符串类型,保留一位小数*/
            qDebug() << "Frame rate:" << sFpsStr << "fps";
            ui->statusbar->showMessage("Connected to server     fps:" + sFpsStr + " fps" );
        }
        /* 重置帧计数器和计时器*/
        if (m_nFrameCount >= 10) {
            m_nFrameCount = 0;
            m_frameTimer.restart();
        }
       /* 提取JPEG图像数据*/
       QByteArray jpegData = m_aRecvBuffer.mid(nStartIndex, nEndIndex + endMarker.size() - nStartIndex);
       QImage image;
       if (image.loadFromData(jpegData, "JPEG")) {
           if (m_nIsColor == 1) {
               image = image.convertToFormat(QImage::Format_Grayscale8);
           }
           int nLabelWidth = ui->labelPicture->width();
           int nLabelHeight = ui->labelPicture->height();
           int nImageWidth = image.width();
           int nImageHeight = image.height();
           double dWidthRatio = static_cast<double>(nLabelWidth) / nImageWidth;
           double dHeightRatio = static_cast<double>(nLabelHeight) / nImageHeight;
           double dScaleFactor = qMin(dWidthRatio, dHeightRatio);
           QImage scaledImage = image.scaled(nImageWidth * dScaleFactor, nImageHeight * dScaleFactor, Qt::KeepAspectRatio);
           ui->labelPicture->setPixmap(QPixmap::fromImage(scaledImage));
           ui->labelPicture->setAlignment(Qt::AlignCenter);
       }
       jpegData.clear();
       m_aRecvBuffer.remove(0, nEndIndex + endMarker.size());
    }

总结

总之,QByteArray 是一个非常实用的类,可以方便地处理二进制数据。在 Qt 中,几乎所有需要处理字节数组的场景都可以使用 QByteArray 来实现。

  • 5
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值