Qt输入输出类使用总结

Qt输入输出类简介

在这里插入图片描述
QTextStream 类(文本流)和 QDataStream 类(数据流)Qt 输入输出的两个核心类,其作用分别如下:

  • QTextStream 类用于对数据进行文本格式的读/写操作,可在 QString、QIODevice或 QByteArray 上运行,比如把数据输出到 QString、QIODevice 或 QByteArray 对象上,或进行相反的操作。
  • QDataStream 类用于对数据进行二进制格式的读/写操作,QDataStream 只可在QIODevice 或 QByteArray 上运行,因为 QString 只存放字符数据。

QIODevice 类是 Qt 中所有 I/O 设备的基础接口类(这是一个抽象类),也就是说 QIODevice及其子类描述的是 I/O 设备,该类为支持读/写数据块的设备提供了通用实现和抽象接口,比如 QFile、QBuffer、QTcpSocket 等。

QIODevice 把设备分为两类:随机存储设备和顺序存储设备

  • 随机存储设备:可定位到任意位置(使用 seek()函数),随机存储设备有 QFile,QTemporaryFile,QBuffer;
  • 顺序存储设备:不支持任意的位置存储,顺序存储设备有 QProcess、QTcpSocket、QUdpSocket 和 QSslSocket。

QTextCodec 类负责 Unicode 与各字符编码之间的转换

QProcess 类与进程相关,QTcpSocket、QUdpSocket 等类与网络数据传输有关

QBuffer 类为 QByteArray 提供了一个 QIODevice 接口,以允许使用 QIODevice 接口来访问 QByteArray。默认情况下,创建一个 QBuffer 时,会自动在内部创建一个 QByteArray缓冲区。

QIODevice::OpenModeFlag 枚举介绍如下:
在这里插入图片描述

QDataStream 类(数据流)

QDataStream 类(数据流)简介

QDataStream 类负责以二进制方式读/写程序中的对象,输入源和输出目样标可以是QIODevice、QByteArray 对象。

字节序:即多字节数据(即大于一个字节的数据)在内存中的存储顺序,有如下两种方式:

  • Little-Endian(LE,小端):即低位字节存储在低地址端,高位字节存储在高地址端;
  • Big-Endian(BE,大端):即高位字节存储在低地址端,低位字节储倣在高地址端。这是 QDataStream 的默认字节序。
    比如对于整数 0x2345,若按 big-endian(大端)顺序存储,则按 0x23、0x45 的顺序存储,若按 little-endian(小端)顺序存储,则以 0x45、0x23 的顺序存储。

对象的存储和传输:若直接把一个对象保存在文件(或其他地方)上是没有意义的,因为对象中通常包含指向其他对象的指针,指针所指对象在下次运行时其内存地址很可能并不相同,因此在保存对象时,保存本次运行时指针的值就毫无意义,对此,需要采取必要的手段来解决保存对象的问题。对象的传输同样会遇到这种问题(比如在客户端和服务端传递对象时,在进程间传递对象时),解决这一问题的方法就是序列化(serializable)或称为串行化。

序列化(serializable):是把对象状态转换为可保存或可传输的形式的过程,与其对应的是反序列化,序列化和反序列化保证了数据易于存储和传输。数据通常以二进制序列的形式进行传输,因此序列化通常是把对象转换为字节序列的过程,其相反过程称为反序列化。

QDataStream 是编码信息的二进制流,它完全独立于主机的操作系统、CPU 和字节序,比如由 Windows 编写的数据流可以由运行 Solaris 的 Sun SPARC 读取。还可使用数据流来读/写原始的未编码的二进制数据。

QDataStream 实现了基本的 C++数据类型的序列化,比如 char,short,int,char *等。更复杂的数据类型的序列化是通过分解原始单元来完成的。

数据流与 QIODevice 紧密合作,QIODevice 表示一个能读/写数据的 I/O 设备,其中 QFile是常见的 I/O 设备。

写入到数据流的每一项都是以预定义的二进制格式编写的,该格式根据写入项的类型而有所不同。

QDataStream 支持的 Qt 类型有 QBrush、QColor、QDateTime、QFont、QPixmap、QString、QVariant 等类型,还包括容器类型,比如 QList、QVector、QSet、QMap 等,支持的 Qt类型的完整列表可参阅帮助文档 Serializing Qt Data Types。

对于整数,建议始终转换为 Qt 整数类型(比如 qint32 等)进入写入,并将其读入为相同的Qt整数类型,这样可以确保获取确定的大小的整数,以避免编译器和平台差异的影响(注:C++语法只规定了 int,short 等类型的最小长度,未规定最大长度)。

使用 QDataStream 读/写二进制数据的步骤如下(以读/写到 QFile 为例):

  • 使用 QDataStream 可方便的使用>>和<<运算符对数据进行读写操作。
  • 使用 QDataStream 读取文件步骤相对来说要多一些,需要如下步骤:
    1)创建一个 QFile 对象;
    2)再打开文件;
    3)然后还需要创建一个 QDataStream 对象并把 QFile 对象绑定到该对象上;
    4)然后才能使用>>和<<运算符进行读取操作。

QDataStream 类函数详解(目前使用频率低)

QTextStream 类(文本流)

QTextStream 类(文本流)简介

字符编码基础知识

怎样将字符转换为二进制形式进行存储,存在一个编码的问题,通常都需进行两次编码

字符集字符的第一次编码是将字符编码为与一个数值(如一个 10 进制整数)相对应,比如把字符 A 编码为 10 进制的 65,B 编码为 66 等。把每一个字符都编码为与一个数值对应就组成了一个字符集,比如常用的 ASCII 字符集Unicode 字符集GB2312 字符集等。

编码(或称为编码字符集):字符的第二次编码就是把第一次编码好的数值再编码为相应的二进制形式,这样计算机就能识别了,比如对于 Unicode 字符集有 3 种不同的二次编码方案,分别是 UTF-8(变长位),UTF-16(16 位)和 UTF-32(32 位),目前使用较多的是使用 UTF-8来存储的 Unicode 字符集。本文把第二次编码后的方案简称为编码,比如 UTF-8 编码,UTF-16 编码等。

字节顺序标记 BOM(Byte Order Mark):BOM 是出现在文本文件头部的一种用于标识文件格式的编码UTF-16 和 UTF-32 通常使用 BOM 来表示文本的字节序字节序对 UTF-8没有意义,因此 UTF-8 不需要使用 BOM 来表明字节序,但可使用 BOM 来表明其编码方式,通常使用 0xEF BB BF 来表明此文本是使用的 UTF-8 编码。UTF-8 不推荐使用无意义的 BOM,但很多程序在保存 UTF-8 编码的文件时仍然带有 BOM(即在文件的开头加上 0x EF BB BF 三个字节),比如 windows 的记事本等,因此在编辑 UTF-8 的文件时,需要注意该文件是否带有 BOM 的问题。

QString 和 QByteArray 简介:QString 存储一个 16 位的 QChar 字符串其中每个 QChar 对应一个 Unicode4.0 字符(即存储的字符含有16位),对于代码值超过65536的Unicode字符使用两个连续的QChar表示QByteArray 类用于存储原始字节和传统的 8 位以’\0’终止的字符串。Qt 内部大量使用了QString,因此通常应使用 QString,QByteArrayy 主要用于存储原始二进制数据

QTextStream 基本规则

二进制文件格式更紧凑,但它是机器语言,不易于人工阅读和编辑,为此可使用文本格式代替二进制格式

QTextStream 类用于对数据进行文本格式的读/写操作,可在 QString、QIODevice 或QByteArray 上运行,使用 QTextStream 可方便的读/写单词、行和数字,另外 QTextStream还对字段填充、对齐和数字格式提供了格式选项的提供支持。

QTextStream 与编码和字符集:

  • QTextStream 在其内部使用 16 位(两字节)长的 QChar 类型存放每个字符,字符集使用Unicode,这与 C++的 iostream 不同,iostream 每个字符的类型由模板参数 charT 指定,标准库已将其特化为 char 和 wchar_t 类型,除此之外还可为 charT 指定其他类型,而QTextStream 的字符类型固定为 QChar 类型,使用此种方式简化了 Qt 流的总体结构,但也增加了字符占据的空间。
  • QTextStream 能在 Unicode 编码与系统的本地编码或其他任意编码间进行转换,且明确的处理了因系统的不同而导致的不同的行尾符的问题(比如,在 Windows 上行尾符是"\r\n",在 UNIX 或 mac OS X 上是"\n"),行尾符还可在打开设备时指定QIODevice::Text 枚举来设置。
  • QTextStream 使用 QTextCodec 类来支持不同的字符集默认使用QTextCodec::codecForLocale()返回的本地编码进行读/写,也可使用 QTextStream::setCodec()函数来重新设置编码
  • QTextStream 支持自动 Unicode 的 BOM 检测,当启用此功能(默认)时,QTextStream将检测 UTF-16 或 UTF-32 的字节顺序标记 BOM(Byte Order Mark),并在读取时切换到适当的 UTF 编解码器。默认情况下,QTextStream 不编写 BOM,但是可以通过调用 setGenerateByteOrderMark(True)来启用 BOM。

QTextStream 有 3 种读取文本文件的方式,如下:

  • 调用 readLine()逐行读取数据,使用 readAll()一次读取整个文件
  • 一个单词接一个单词的读取,单词由空格分开,且可自动跳过前导空格通过在 QString、QByteArray 或 char*缓冲区上使用>>操作符来实现
  • 一个字符接一个字符的读取,通过在 QChar 或 char 类型上使用使用>>操作符来实现。可使用 skipWhiteSpace()来跳过空格

格式控制:

  • QTextStream 模仿了的控制符(也称为操作器),比如可使用 dec 等流控制符以 10 进制形式显示数字,另外还可使用 setIntegerBase()、setNumberFlags()等函数来设置格式。
  • 当从文本流中读取数字时,QTextStream 会自动检测数字的基数,比如,若数字以 0x开始,则将被假定为 16 进制形式,若以 1~9 开头,则被假定为 10 进制形式。还可使用 dec 等流控制符、setIntegerBase()函数来设置基数,从而停止自动检测。
  • QTextStream 还可以进行基本数字类型和字符串之间的转换。

写入文本数据比较容易,但读取就比较难了,比如:

out<<"AAA"<<"BBB" //把 AAA 和 BBB 写入流
in>>s1>>s2; //试图从流中读取 AAA 到 s1,BBB 到 s2,

若使用 QTextStream 不能获得这个结果,此时 s1=“AAABBB”,而 s2 什么也没有,若使用QDataStream 则能使 s1=“AAA”,s2=“BBB”,因为 QDataStream 在字符串数据前面保存了每个字符串的长度。

由于文本流使用缓冲区(用于存储中间数据,这减少了对设备的访问数量),所以不应该使用设备的相应函数直接读取,比如,若一个 QFile 直接使用 QFile::readLine()读取,而不是使用 QTextStream::reaLine(),那么文本流的内部位置会与文件的位置不同步。

QTextStream 类中的函数

对 QTextStream 流的操作函数

1)构造函数:
QTextStream();
QTextStream(QIODevice *device); //构造一个在设备 device 上运行的 QTextStream

QTextStream(FILE *fileHandle, QIODevice::OpenMode openMode = QIODevice::ReadWrite);
此函数用于在控制台进行输入输出。

QTextStream(QString *string, QIODevice::OpenMode openMode = QIODevice::ReadWrite);
构造一个在字符串 string 上运行的 QTextStream,打开模式由 openMode 指定。

QTextStream(QByteArray *array, QIODevice::OpenMode openMode = QIODevice::ReadWrite);
构造一个在 array 上运行的 QTextStream,在内部 array 会由 QBuffer 包装。

QTextStream(const QByteArray &array, QIODevice::OpenMode openMode = QIODevice::ReadOnly);
构造一个在 array 上运行的 QTextStream,无论 openMode 的值如何,array 都以只读方式访问。

2)void flush();
刷新等待写入设备的缓冲区数据,若 QTextStream 对字符串进行操作,则此函数什么也不做。如果调用此函数,QTextStream 会将写入缓冲区中的所有数据清空到设备中,并调用设备上的 flush()。该函数的作用其实就是刷新缓冲区

3)bool atEnd() const;
若没有更多的数据从QTextStream中读取(即到达流的末尾),则返回true,否则返回false。

4)void resetStatus(); //重置 QTextStream 的状态
Status status() const; //返回 QTextStream 的状态
void setStatus(Status status);
设置 QTextStream 的状态。直到调用 resetStatus()之前将忽略对 setStatus()的后续调用。Status 枚举见下表
在这里插入图片描述
5)QIODevice *device() const; //返回与 QTextStream 关联的当前设备,若未分配设备,则返回 0
void setDevice(QIODevice *device);
把当前设备设置为 device,若已分配了设备,则 QTextStream 在更换旧设备之前调用QTextStream::flush()。注意:此函数会把语言环境重置为默认语言环境,将编解码器重置为默认编解码器 QTextCodec::codecForLocale()

6)QString *string() const; //返回分配给 QTextStream 的 string,若未分配,则返回 0
void setString(QString *string, QIODevice::OpenMode openMode = QIODevice::ReadWrite);
使用打开模式 openMode 重新设置 QTextStream 的设备为 string,若设备已分配,则QTextStream 在更换旧设备之前调用 QTextStream::flush()

读取流中的数据及位置函数

1)QString read(qint64 maxlen); //从流中读取 maxlen 个字符,并将其作为 QString 返回。

2)QString readAll();
从流中读取全部内容,并将其作为 QString 返回,处理大型文件时应避免使用此函数,因为会消耗大量内存。

3)QString readLine(qint64 maxlen = 0);
从流中读取一行文本,并将其作为 QString 返回,允许的最大行长度为 maxlen,若流的长度超过 maxlen,则行将在 maxlen 之后被拆分,并以部分的形式返回。若 maxlen为 0,则行可以是任意长度。返回的行没有行尾字符(“\n"或”\r\n"),若流已到达文件末尾,则返回空的 QString。

4)bool readLineInto(QString *line, qint64 maxlen = 0); //qt5.5
从流中读取一行文本到 line,若 line 为 0,则不存储读取的行。允许的最大行长度为maxlen,若流的长度超过 maxlen&

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

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

相关文章

Ubuntu切换内核版本

#安装内核安装工具 sudo apt-get install software-properties-common sudo add-apt-repository ppa:cappelikan/ppa sudo apt-get update sudo apt-get install mainline#安装指定内核版本(有些版本并不能安装成功) mainline install 5.14.10#更新GRUB配置 sudo update-grub#查…

Python实现将LabelMe生成的JSON格式转换成YOLOv8支持的TXT格式

标注工具 LabelMe 生成的标注文件为JSON格式&#xff0c;而YOLOv8中支持的为TXT文件格式。以下Python代码实现3个功能&#xff1a; 1.将JSON格式转换成TXT格式&#xff1b; 2.将数据集进行随机拆分&#xff0c;生成YOLOv8支持的目录结构&#xff1b; 3.生成YOLOv8支持的YAML文件…

操作教程|通过DataEase开源BI工具对接金山多维表格

前言 金山多维表格是企业数据处理分析经常会用到的一款数据表格工具&#xff0c;它能够将企业数据以统一的列格式整齐地汇总至其中。DataEase开源数据可视化分析工具可以与金山多维表格对接&#xff0c;方便企业更加快捷地以金山多维表格为数据源&#xff0c;制作出可以实时更…

【网络版本计算器的实现】

本章重点 理解应用层的作用, 初识HTTP协议理解传输层的作用, 深入理解TCP的各项特性和机制对整个TCP/IP协议有系统的理解对TCP/IP协议体系下的其他重要协议和技术有一定的了解学会使用一些分析网络问题的工具和方法 ⭐注意!! 注意!! 注意!! 本课是网络编程的理论基础.是一个服务…

Antd Vue项目引入TailwindCss之后出现svg icon下移,布局中的问题解决方案

目录 1. 现象&#xff1a; 2. 原因分析&#xff1a; 3. 解决方案&#xff1a; 写法一&#xff1a;扩展Preflight 写法二&#xff1a; 4. 禁用 Preflight 1. 现象&#xff1a; Antd Vue项目引入TailwindCss之后出现svg icon下移&#xff0c;不能对齐显示的情况&#xff0…

爬虫实训案例:中国大学排名

近一个月左右的时间学习爬虫&#xff0c;在用所积累的知识爬取了《中国大学排名》这个网站&#xff0c;爬取的内容虽然只是可见的文本&#xff0c;但对于初学者来说是一个很好的练习。在爬取的过程中&#xff0c;通过请求数据、解析内容、提取文本、存储数据等几个重要的内容入…

React-router 最佳实践

使用的是 BrowserRouter&#xff0c;Routes 和 Route&#xff0c;这是 react-router-dom v5 和 v6 都支持的 API。这种方式的优点是路由配置和应用的其它部分是紧密集成的&#xff0c;这使得路由配置更加直观和易于理解 // router/index.js import { BrowserRouter as Router,…

【Qt 学习笔记】Qt常用控件 | 布局管理器 | 网格布局Grid Layout

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Qt常用控件 | 布局管理器 | 网格布局Grid Layout 文章编号&#xff1a…

成品短视频APP源码搭建

在数字化时代&#xff0c;短视频已成为全球范围内的流行趋势&#xff0c;吸引了大量的用户和内容创作者。对于有志于进入短视频领域的企业和个人来说&#xff0c;成品短视频APP源码搭建提供了一条快速、高效的路径。本文将探讨成品短视频APP源码搭建的过程及其优势&#xff0c;…

Mac维护神器CleanMyMac X成为你的苹果电脑得力助手

在数字化时代&#xff0c;Mac电脑已成为众多用户的首选。然而&#xff0c;随着频繁的使用和数据量的日益增长&#xff0c;许多Mac用户面临着系统杂乱、存储空间不足以及隐私保护等问题。幸运的是&#xff0c;"CleanMyMac X"这款优化和清理工具应运而生&#xff0c;它…

[论文笔记]REACT: SYNERGIZING REASONING AND ACTING IN LANGUAGE MODELS

引言 今天带来一篇经典论文REACT: SYNERGIZING REASONING AND ACTING IN LANGUAGE MODELS的阅读笔记&#xff0c;论文中文意思是 在语言模型中协同推理和行动。 虽然大型语言模型(LLMs)在语言理解和互动决策任务中展现出强大的能力&#xff0c;但它们在推理(例如思维链提示)和…

【算法】栈算法——最小栈

题解&#xff1a;最小栈(栈算法) 目录 1.题目2.题解3.总结 1.题目 题目链接&#xff1a;LINK 这个题目题意说的有点绕&#xff0c;说白了让你在常数时间内检索到最小元素就是O(1)时间复杂度下找到栈中最小的元素。 2.题解 思路&#xff1a;这个栈可以内嵌套两个库栈来进行…

商品发布功能

文章目录 1.SPU和SKU介绍1.SPU2.SKU3.两者之间的关系 2.完成商品发布界面1.组件引入1.commoditylaunch.vue 引入到 src/views/modules/commodity下2.multiUpload.vue 引入到 src/components/upload/multiUpload.vue 2.创建菜单1.创建目录2.创建菜单&#xff0c;注意菜单路由要匹…

开源博客项目Blog .NET Core源码学习(25:App.Hosting项目结构分析-13)

本文学习并分析App.Hosting项目中后台管理页面的文章管理页面。   文章管理页面用于显示、检索、新建、编辑、删除文章数据&#xff0c;以便在前台页面的首页、文章专栏、文章详情页面显示文章数据。文章管理页面附带一新建及编辑页面&#xff0c;以支撑新建和编辑文章数据。…

交换机部分综合实验

实验要求 1.内网IP地址使用172.16.0.0/16 2.sw1和sW2之间互为备份; 3.VRRP/mstp/vlan/eth-trunk均使用; 4.所有pc均通过DHcP获取Ip地址; 5.ISP只配置IP地址; 6.所有电脑可以正常访问IsP路由器环回 实验拓扑 实验思路 1.给交换机创建vlan&#xff0c;并将接口划入vlan 2.在SW1和…

传输层 --- UDP

一、简述与回顾 传输层&#xff1a;负责数据能够从发送端传输接收端 在TCP/IP协议中&#xff0c;我们用"源IP"&#xff0c;"源端口号"&#xff0c;"目的IP"&#xff0c;"目的端口号"&#xff0c;和"协议号"来表示一个通信。…

Android studio关闭自动更新

Windows下&#xff1a; 左上角file - setting - Appearance & Behavier - system setting - update - 取消勾选

golang通过go-aci适配神通数据库

1. go-aci简介 go-aci是神通数据库基于ACI(兼容Oracle的OCI)开发的go语言开发接口&#xff0c;因此运行时需要依赖ACI驱动和ACI库的头文件。支持各种数据类型的读写、支持参数绑定、支持游标范围等操作。 2. Linux部署步骤 2.1. Go安装&#xff1a; 版本&#xff1a;1.9以上…

Spring Cache基本使用

Spring 从 3.1 版本开始定义缓存抽象来统一不同的缓存技术&#xff1b;在应用层面与后端存储之间&#xff0c;提供了一层抽象&#xff0c;这层抽象目的在于封装各种可插拔的后端存储( ehcache, redis, guava)&#xff0c;最小化因为缓存给现有业务代码带来的侵入。 一、Spring…

机器学习实验 --- 逻辑回归

第1关:逻辑回归核心思想 任务描述 本关任务:根据本节课所学知识完成本关所设置的编程题 #encoding=utf8 import numpy as npdef sigmoid(t):完成sigmoid函数计算:param t: 负无穷到正无穷的实数:return: 转换后的概率值:可以考虑使用np.exp()函数#********** Begin *******…