【Qt】QByteArray详解

QByteArray 是 Qt 框架中用于处理原始字节数据的核心类,其实质可以概括为以下几点:


1. 底层数据结构

连续内存块:存储一段连续的字节数据(char*),类似 std::vector<char>,但针对 Qt 框架做了优化。
自动内存管理:内部自动分配和释放内存,无需手动管理。
隐式共享(写时复制):使用 Implicit Sharing 技术,多个 QByteArray 对象共享同一份数据,直到修改时才进行深拷贝,以节省内存和计算资源。


2. 核心特性

二进制数据支持:可存储任意二进制数据(如图片、音频、协议数据),不依赖字符编码。
与 C 字符串兼容:数据默认以 \0 结尾,可通过 data()constData() 直接获取 const char* 指针,方便与 C 函数交互。
动态大小:支持动态扩容(如 append()resize()),无需预分配固定大小。


3. 主要用途

网络通信:序列化/反序列化数据(如通过 QNetworkRequest 发送二进制内容)。
文件 I/O:读写二进制文件(如 QFile::readAll() 返回 QByteArray)。
编码转换:作为 QString 与编码(如 UTF-8、Latin-1)之间的桥梁(例如 QString::toUtf8() 返回 QByteArray)。
加密/哈希:处理加密后的二进制结果(如 QCryptographicHash 的哈希值)。


4. 与 QString 的区别

特性QByteArrayQString
数据本质原始字节(charUnicode 字符(QChar,UTF-16)
编码感知无(直接处理字节)有(自动处理 Unicode 转换)
适用场景二进制数据、协议、文件文本处理、用户界面显示
C 字符串兼容性直接兼容(data()需转换(toUtf8()

5. 关键方法示例

// 创建并初始化
QByteArray data("Hello");  // 内容: 'H' 'e' 'l' 'l' 'o' '\0'// 追加数据
data.append(0x41);         // 追加字节 0x41(ASCII 'A')// 获取指针
const char* cstr = data.constData(); // 指向 "HelloA\0"// 转换为十六进制字符串
QByteArray hex = data.toHex(); // "48656c6c6f41"// 内存共享验证
QByteArray copy = data;    // 隐式共享,不复制数据
copy[0] = 'h';             // 触发写时复制,data 和 copy 数据分离

6. 性能与注意事项

高效操作:避免频繁调用 data() 获取指针,可能导致隐式共享分离。
二进制安全:可包含 \0 字节,size() 返回实际数据长度(不包括结尾的 \0)。
编码转换:与 QString 互转时需明确编码(如 fromUtf8()toLatin1())。


常用接口
QByteArray::fromHex() 的输入参数类型是 QByteArray


详细说明

函数签名

static QByteArray QByteArray::fromHex(const QByteArray &hexEncoded);

输入必须是一个 QByteArray 对象。

常见用法
• 直接传入 QByteArray
cpp QByteArray hexData = "48656c6c6f"; // 十六进制字符串 QByteArray data = QByteArray::fromHex(hexData);
• 若使用 QString 作为输入,需先转换为 QByteArray(例如用 toLatin1()toUtf8()):
cpp QString hexStr = "48656c6c6f"; QByteArray data = QByteArray::fromHex(hexStr.toLatin1());


参数要求

  1. 内容必须是有效的十六进制字符串
    • 仅允许字符 0-9a-fA-F
    • 其他字符(如空格、gx 等)会被自动忽略。

  2. 处理奇数字符长度
    • 如果输入字符串长度为奇数,fromHex() 会自动在最前面补零,使其成为偶数长度。
    • 例如:输入 "123" 会被当作 "0123" 解析。


示例

// 示例1:直接使用 QByteArray
QByteArray hex1 = "31393231"; // 对应 "19121" 的十六进制
QByteArray a1 = QByteArray::fromHex(hex1);
// 结果: a1 = "19121", size = 5// 示例2:使用 QString 转换
QString hexStr2 = "31393231";
QByteArray a2 = QByteArray::fromHex(hexStr2.toUtf8());
// 结果: a2 = "19121", size = 5// 示例3:奇数字符长度
QByteArray hex3 = "abc"; // 奇数长度
QByteArray a3 = QByteArray::fromHex(hex3);
// 解析为 "0abc",结果: a3 = "\x0a\xbc"

常见错误

直接传递 QString

QString hexStr = "31393231";
QByteArray data = QByteArray::fromHex(hexStr); // 错误!类型不匹配

必须先将 QString 转换为 QByteArray(例如 hexStr.toLatin1())。

包含非十六进制字符

QByteArray hexData = "1g2h"; // 'g' 和 'h' 无效
QByteArray data = QByteArray::fromHex(hexData); // 自动忽略无效字符,解析为 "12"

QByteArray::fromHex() 的补零规则:
QByteArray a = QByteArray::fromHex(QString::toLatin1("19121"));size 为 3


详细步骤解析

  1. 输入字符串处理
    QString::toLatin1("19121") 将字符串 "19121" 转换为 Latin-1 编码的 QByteArray,其字节内容为 0x31 0x39 0x31 0x32 0x31(对应 ASCII 字符 '1' '9' '1' '2' '1')。

  2. fromHex() 的转换规则
    fromHex() 将输入的字符串视为十六进制编码数据,每两个字符转换成一个字节
    • 若输入长度为奇数,自动在最前面补零使其成为偶数长度。
    • 对于输入 "19121"(长度为 5,奇数):
    ◦ 补零后等效于 "019121"(长度为 6,偶数)。
    ◦ 分组为 "01""91""21"

  3. 转换结果
    "01"0x01
    "91"0x91
    "21"0x21
    • 最终 QByteArray a 包含 3 字节:[0x01, 0x91, 0x21],故 a.size() = 3


验证代码

QByteArray hexData = QString::toLatin1("19121"); // 内容: "19121" (5字节)
QByteArray a = QByteArray::fromHex(hexData);
qDebug() << a.size(); // 输出: 3
qDebug() << a.toHex(); // 输出: "019121"(实际存储的字节为 0x01 0x91 0x21)

关键点

fromHex() 的输入必须是有效的十六进制字符(0-9a-fA-F),其他字符会被忽略。
• 补零规则确保奇数字符串能正确解析,避免数据截断。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/73789.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Stable Diffusion vue本地api接口对接,模型切换, ai功能集成开源项目 ollama-chat-ui-vue

1.开启Stable Diffusion的api服务 编辑webui-user.bat 添加 –api 开启api服务&#xff0c;然后保存启动就可以了 2.api 文档地址 http://127.0.0.1:7860/docs3. 文生图 接口 地址 /sdapi/v1/txt2img //post 请求入参 {enable_hr: false, // 开启高清hrdenoising_stre…

CentOS 7 部署RuoYi 项目

换源 备份现有的 YUM 源配置文件 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup 默认的 CentOS 官方镜像源替换为阿里云的镜像源&#xff0c;以提高下载速度和稳定性。 curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.co…

从 WPF 到 MAUI:跨平台 UI 开发的进化之路

一、引言 在软件开发领域&#xff0c;用户界面&#xff08;UI&#xff09;开发一直是至关重要的环节。随着技术的不断发展&#xff0c;开发者对于创建跨平台、高性能且美观的 UI 需求日益增长。Windows Presentation Foundation&#xff08;WPF&#xff09;和 .NET Multi - pl…

C++ stack容器总结

stack 基本概念 概念&#xff1a; stack是一种后进先出(Last In First Out, LIFO)的数据结构&#xff0c;它只有一个出口 栈中只有顶端的元素才可以被外界使用&#xff0c;因此栈不允许有遍历行为 栈中进入的数据称为----入栈&#xff08;PUSH&#xff09; 栈中出去的数据成…

【SDMs分析1】基于ENMTools R包的生态位分化分析和图像绘制(identity.test())

基于ENMTools包的生态位分化 1. 写在前面2. 生态位分化检验案例13. 生态位分化检验案例21. 写在前面 最近学了一个新的内容,主要是关于两个物种之间生态位分化检验的 R 语言代码。生态位分化是物种分布模型(SDM )研究中的关键部分,许多 SCI 论文都会涉及这一分析。该方法主…

SpringBoot 7 种实现 HTTP 调用的方式

1. HttpClient HttpClient是Apache基金会提供的一个用于发送HTTP请求的Java客户端库。 尽管它功能强大&#xff0c;但由于其API设计较为复杂且包体积庞大&#xff0c;在一些轻量级的应用场景中可能显得过于臃肿。 不过&#xff0c;在需要高度定制化的HTTP请求时&#xff0c;H…

Ubuntu与Windows之间相互复制粘贴的方法

一、打开Ubuntu终端 二、卸载已有的工具 sudo apt-get autoremove open-vm-tools 三、安装工具 sudo apt-get install open-vm-tools-desktop 四、重启 直接输入reboot 注&#xff1a;有任何问题欢迎评论区交流讨论或者私信&#xff01;

ECharts实现数据可视化

ECharts实现数据可视化 一、Echarts的简介二、Echarts使用教程1.下载echarts.min.js文件2.编写echarts代码&#xff08;1&#xff09;创建渲染实列&#xff08;2&#xff09;修改option达到预期的效果&#xff08;3&#xff09;创建配置项到实例中 三、Echarts的基础配置四、前…

ArcGIS 10.8.1之后发布栅格数据的MapServer 动态工作空间 替换数据源渲染问题

背景 经过测试&#xff0c;Server 10.8.1、11.0、11.1发布相关服务设置动态空间之后&#xff0c;前端都无法自动读取同名的clr色彩映射表文件进行渲染&#xff0c;服务都是由ArcGIS Pro进行发布。 原因 基于ArcMap发布的服务才支持&#xff0c;但是10.8.1之后不支持ArcMap发…

vscode在使用 alt + tab 切换程序窗口时,输入法总是自动变为中文模式

因为需要在 vscode 中编写代码&#xff0c;将输入法设为英文模式&#xff0c;但是用 alt tab 切换到浏览器查看文档&#xff0c;此时浏览器也是英文模式&#xff0c;但是再切回 vscode 后就变为中文模式了&#xff0c;需要使用 shift 键切换为英文模式&#xff0c;一次两次还好…

【Linux加餐-网络命令】

一、Ping命令 Ping 是一种网络工具&#xff0c;用于测试主机之间的连通性。它通过发送 ICMP&#xff08;Internet Control Message Protocol&#xff09;回显请求 报文到目标主机&#xff0c;并等待目标主机返回 ICMP 回显应答 报文&#xff0c;从而判断网络是否通畅以及测量往…

Maven工具学习使用(六)——聚合与继承

Maven的聚合特性能够把项目的各个模块聚合在一起构建,而Maven的继承特性则能帮助抽取个模块相同的依赖和插件等配置,在简化POM的同时,还能促进各个模块配置的一致性。 一般说来一个项目的子模块都应该使用同样的groupId,如果他们一起开发和发布,还应该使用同样的version,…

vulhub靶场jangow-01-1.0.1

启动靶机时点shift停在这个界面 点e进入编辑页面&#xff0c;把ro改成rw signie init/bin/bash Ctrlx保存&#xff0c;ip a查看网卡信息 vim /etc/network/interfaces 把enp0s17改为ens33&#xff0c;保存退出 重启靶机&#xff0c;nmap扫ip ip为192.168.93.179 nmap扫端口 扫…

C++11QT复习 (四)

Day6-1 输入输出流运算符重载&#xff08;2025.03.25&#xff09; 1. 拷贝构造函数的调用时机 2. 友元2.1 友元函数 3. 输入输出流运算符重载3.1 关键知识点3.2 代码3.3 关键问题3.4 完整代码 4. 下标访问运算符 operator[]4.1 关键知识点4.2 代码 5. 函数调用运算符 operator…

数仓架构告别「补丁」时代!全新批流一体 Domino 架构终结“批流缝合”

在数字化转型的浪潮中&#xff0c;企业对数据处理的需求日益复杂多变&#xff0c;传统的批处理和流处理架构已难以满足日益增长的性能和时效性要求。在此背景下&#xff0c;YMatrix CEO 姚延栋发布了深度文章《数仓架构告别「补丁」时代&#xff01;全新批流一体 Domino 架构终…

一文详解QT环境搭建:ubuntu20.4安装配置Qt5

随着软件开发技术的不断进步&#xff0c;跨平台应用程序的需求日益增长&#xff0c;开发者们面临着如何在不同操作系统之间保持代码的一致性和效率的问题。Qt作为一个成熟的跨平台C框架&#xff0c;在这方面提供了卓越的支持&#xff0c;不仅简化了GUI应用程序的创建过程&#…

安全+低碳+高效:Acrel-3000助力企业打造未来型电能管理体系-安科瑞黄安南

一 背景 电能因为方便传输、易于转换、便于控制等特性&#xff0c;成为广大企事业单位生产、办公最主要的能量来源。双碳背景下&#xff0c;由于电能清洁、高效、零排放的特点&#xff0c;能源消费侧将逐步以电代煤、以电代油、以电代气&#xff0c;形成以电为中心的能源消费体…

Docker 安装 RabbitMQ

以下是在Docker中安装RabbitMQ并实现配置、数据、日志文件映射的完整步骤。 步骤 1&#xff1a;创建本地目录结构 # 创建配置、数据、日志目录 mkdir -p /root/docker/rabbitmq/{conf,data,logs}# 目录结构说明&#xff1a; # - conf: 存放自定义配置文件 # - data: 持久化存储…

SAP-ABAP:SAP数据集成全场景技术指南(BAPI、RFC、IDOC、BATCHJOB、ODATA、WEBSERVICE):从实时交互到批量处理

SAP数据集成全场景技术指南:从实时交互到批量处理 #mermaid-svg-hpPMerJYUerla0BJ {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-hpPMerJYUerla0BJ .error-icon{fill:#552222;}#mermaid-svg-hpPMerJYUerla0BJ .er…

运维规则之总结(Summary of Operation and Maintenance Rules)

运维规则之总结 在运维领域&#xff0c;经验和流程往往决定了系统的稳定性与可靠性。一个运维人&#xff0c;总结出了以下10条运维规则&#xff0c;涵盖了从基础管理到高级策略的全面内容&#xff0c;旨在帮助运维人员更好地应对各种挑战&#xff0c;确保系统的平稳运行。 1.…