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.mzph.cn/news/838899.shtml

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

相关文章

Linux-文件或目录权限

在使用 ll 时&#xff0c;可以查看文件夹内容的详细信息&#xff0c;信息的第1位表示类型&#xff0c;具体信息如下&#xff1a; 类型说明-普通文件d文件夹b块设备文件c字符设备文件p管道文件s套接口文件 第2-10位表示权限&#xff0c; 举例&#xff1a;rwxr-xr-x 类型说明r…

业务架构核心要素之间的关系

背景 前面已经对业务架构的概念和发展简史有了初步的了解&#xff0c;现在主流的业务架构就是价值流能力&#xff0c;在这套架构体系中&#xff0c;有四个核心元素&#xff0c;分别是价值流、业务能力、信息、组织。 这四个核心元素&#xff0c;特别是对于价值流以及业务能力…

查看主机的php参数short_open_tag 是否为 on

我想要查看主机的php参数short_open_tag 是否为 on&#xff0c;由于我使用的是Hostease的Linux虚拟主机产品&#xff0c;在cPanel面板中并没有找到这个参数选项&#xff0c;因此无法查看。这边联系了Hostease技术支持了解&#xff0c;可以通过以下方式进行查看。 1.先登陆cPane…

Shell编程之条件判断语句

目录 一、条件判断 1、test命令 2、文件测试 3、整数值比较 4、字符串判断 5、逻辑测试 二、if语句 1、if单分支语句 2、双分支语句 3、多分之语句 4、case 分支语句 一、条件判断 Shell环境根据命令执行后的返回状态值&#xff08;echo $?&#xff09;来判断是否执行成…

鸿蒙HarmonyOS开发中的易混点归纳-持续补充中

相关文章目录 鸿蒙HarmonyOS开发术语全解&#xff1a;小白也能看懂&#xff01; 文章目录 相关文章目录前言一、build()函数和Builder装饰器&#xff1f;二、自定义组件和系统组件&#xff08;内置组件&#xff09;三、组件和页面四、自定义弹窗和其他弹窗总结 前言 一、build…

SpringBoot(五)之新增注解

SpringBoot&#xff08;五&#xff09;之新增注解 文章目录 SpringBoot&#xff08;五&#xff09;之新增注解核心注解EnableAutoConfiguration**SpringBootApplication** 条件注解Spring原生Conditional注解手写Conditional注解**ConditionalOnProperty****ConditionalOnMissi…

Logrus IT的供应商经理如何找到优秀地翻译人员

在现代世界&#xff0c;翻译和本地化可以使企业打入新市场并与来自不同国家的客户互动&#xff0c;从而对企业的成功起到决定性作用。翻译过程中的一个关键部分是寻找和招聘翻译。在Logrus IT&#xff0c;这是Anna Gulenkova的工作&#xff0c;我们决定和她谈谈她是如何做到的。…

BUUCTF---misc---我吃三明治

1、下载附件是一张图片 2、在winhex分析&#xff0c;看到一串整齐的编码有点可疑&#xff0c;保存下来&#xff0c;拿去解码&#xff0c;发现解不了&#xff0c;看来思路不对 3、再仔细往下看的时候也发现了一处这样的编码&#xff0c;但是这次编码后面多了一段base编码 4、拿去…

最长前缀数组

欢迎关注更多精彩 关注我&#xff0c;学习常用算法与数据结构&#xff0c;一题多解&#xff0c;降维打击。 基本问题 给定一个字符串s, 返回一个数组Z, Z[i]代表子串s[i…n] 与s最长公共前缀的长度。 朴素做法 可以枚举所有s[i…n]子串&#xff0c;然后与s一一比较&#x…

ERROR TypeError: Cannot read property ‘tapPromise‘ of undefined

问题概要 vue项目运行npm run build打包时&#xff0c;报了ERROR TypeError: Cannot read property ‘tapPromise’ of undefined TypeError: Cannot read property ‘tapPromise’ of undefined的错误。 解决方式 根据github中compression-webpack-plugin源码issues里的提示 …

C#--SVG矢量图画法示例

1.代码示例 <Viewbox Grid.Column"1" Grid.ColumnSpan"1" Grid.RowSpan"1" ><Path Name"ValveShape" Stroke"Black" Data"M 50,0 L 150,200 L 50,200 L 150,0 Z" Width"200" Height"…

经常出差用哪些办公软件记录工作?可多设备同步使用的便签笔记软件

对于许多职场人士来说&#xff0c;出差已成为工作常态。在旅途中&#xff0c;如何高效处理工作&#xff0c;确保信息不遗漏&#xff0c;成为了一个不小的挑战。那么&#xff0c;对于经常需要移动办公的我们&#xff0c;哪款办公软件才是最佳选择呢&#xff1f;可多设备同步使用…

5.23 学习总结

一.项目优化&#xff08;语音通话&#xff09; 实现步骤&#xff1a; 1.用户发送通话申请&#xff0c;并处理通话请求&#xff0c;如果同意&#xff0c;为两个用户之间进行连接。 2.获取到电脑的麦克风和扬声器&#xff0c;将获取到的语音信息转换成以字节数组的形式传递。 …

DataBinding viewBinding(视图绑定与数据双向绑定)简单案例 (kotlin)

先上效果&#xff1a; 4个view的文字都是通过DataBinding填充的。交互事件&#xff1a;点击图片&#xff0c;切换图片 创建项目&#xff08;android Studio 2023.3.1&#xff09; Build.gradle(:app) 引入依赖库&#xff08;完整源码&#xff09; buildFeatures { vie…

java中的HashSet类

一、HashSet类 实现了Set接口&#xff0c;无法存储重复元素 特点&#xff1a;元素位置无序、无索引、底层是HashMap 1、构造方法 内部是HashMap的构造方法 2、add方法 (1)元素在底层存储使用到了三种数据结构&#xff1a;hash数组、链表、树 (2)添加流程&#xff08;根据…

告别登录烦恼,WPS免登录修改器体验!(如何实现不登录使用WPS)

文章目录 &#x1f4d6; 介绍 &#x1f4d6;&#x1f3e1; 演示环境 &#x1f3e1;&#x1f4d2; 解决方案 &#x1f4d2;&#x1f388; 获取方式 &#x1f388;⚓️ 相关链接 ⚓️ &#x1f4d6; 介绍 &#x1f4d6; 想象一下&#xff0c;如果你能够绕过繁琐的登录流程&#x…

C# WinForm —— 22 Forms.Timer 组件介绍与使用

1. 简介 Timer 计时器 组件不会出现在窗体中&#xff0c;每隔 定义的间隔时间&#xff0c;就会触发事件&#xff0c;主要应用于Windows应用程序&#xff0c;独占一个线程&#xff0c;可以修改 UI 元素 属性 属性解释(Name)控件ID&#xff0c;在代码里引用的时候会用到,一般…

运营美区TikTok小店常见问题汇总,你中了几个?

大家好&#xff0c;我是IPdodo的小编&#xff0c;专注于分享出海网络解决方案&#xff0c;致力于为TikTok运营人提供解决视频0播放、直播间卡顿、不进人甚至封号等问题的跨境网络专线。目前已经帮助数千位用户成功开启跨境业务。 今天&#xff0c;将针对美区TikTok小店的常见问…

Swift使用JSONDecoder处理json数据,实现json序列化和反序列化

Json数据处理是开发中不可获取的一项技能&#xff0c;如果你不会处理json数据&#xff0c;那你离失业就不远了&#xff0c;所以学完了swift基础教程&#xff0c;还是先老老实实学习一下json处理吧&#xff0c;有了这项技能&#xff0c;你才可以继续下一个网络请求阶段的开发&am…

Git总结超全版

最近想系统的回顾一下Git的使用&#xff0c;如果只想快速的集成git到idea&#xff0c;可以参考另一篇我的博客中的git部分 目录 版本管理工具简介Git安装与配置Git远程仓库配置 Git常用命令为常用命令配置别名(可选)Git忽略文件.gitignore一些概念*本地仓库操作删除仓库内容 *远…