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&

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JS、Go、Rust 错误处理的不同 - JS 可以不用 Try/Catch 吗?

原文&#xff1a;Mateusz Piorowski - 2023.07.24 先来了解一下我的背景吧。我是一名软件开发人员&#xff0c;有大约十年的工作经验&#xff0c;最初使用 PHP&#xff0c;后来逐渐转向 JavaScript。 大约五年前&#xff0c;我开始使用 TypeScript&#xff0c;从那时起&#…

Go微服务——go-micro v4安装使用

安装go-micro 打开cmd窗口&#xff0c;执行以下命令 go install github.com/go-micro/cli/cmd/go-microlatest测试是否成功安装 go-micro -v创建服务 go-micro new service helloworldwindows 安装make 安装地址 https://gnuwin32.sourceforge.net/packages/make.htm 配置…

python从0开始学习(九)

前言 上一篇文章我们介绍了python中的序列类型和元组类型&#xff0c;本篇文章将接着往下将。 1、字典类型 字典类型是根据一个信息查找另一个信息的方式所构成的“键值对”&#xff0c;它表示索引用的键和对应的值构成的成对关系。它是一个可变数据类型&#xff0c;也就是说它…

JAVA基础知识100题练习、蓝桥杯竞赛题,编程基础必练题!

各位编程小伙伴们&#xff0c;这里可是作者花费了无数个日日夜夜&#xff0c;熬秃了不知道多少根头发&#xff0c;凭借着那超级无敌多年的编程经验&#xff0c;拼死拼活、千辛万苦总结出来的呀&#xff01;这可是各种开发语言都绝对必须要练的基础编程知识哇&#xff01;什么九…

jenkins自动化部署详解

一、准备相关软件 整个自动化部署的过程就是从git仓库拉取最新代码&#xff0c;然后使用maven进行构建代码&#xff0c;构建包构建好了之后&#xff0c;通过ssh发送到发布服务的linux服务器的目录&#xff0c;最后在此服务器上执行相关的linux命令进行发布。 此篇文章jenkins…

Linux gurb2简介

文章目录 前言一、GRUB 2简介二、GRUB 2相关文件/文件夹2.1 /etc/default/grub文件2.2 /etc/grub.d/文件夹2.3 /boot/grub/grub.cfg文件 三、grubx64.efi参考资料 前言 简单来说&#xff0c;引导加载程序&#xff08;boot loader&#xff09;是计算机启动时运行的第一个软件程…

262 基于matlab的一级倒立摆仿真

基于matlab的一级倒立摆仿真&#xff0c;在对一级倒立摆进行数学建模的基础上&#xff0c;对模型进行线性化&#xff0c;得到其状态空间模型&#xff0c;利用二次型最优控制方法得出控制率。输出角度和位置优化曲线。程序已调通&#xff0c;可直接运行。 262 一级倒立摆仿真 状…

Sui生态DeFi项目Cetus和Aftermath宣布启动孵化器

Sui DeFi中的去中心化交易所Cetus和Aftermath Finance联合Sui基金会宣布启动新的孵化器&#xff0c;为初创项目提供更多可行性途径。这两个DeFi项目在Sui上有着较长的历史&#xff0c;自去年一同与主网推出以来&#xff0c;目前在TVL方面位居前五。这两个项目的持久性和成功使它…

构建品牌长期价值:海外KOC营销的持续性策略解析

在当今数字化时代&#xff0c;随着社交媒体的兴起&#xff0c;消费者对于品牌的信任和认可越来越依赖于个人的推荐和体验。因此&#xff0c;KOC营销成为了品牌推广中的重要策略之一。但是&#xff0c;要想构建品牌的长期价值&#xff0c;单纯地依靠一次性的KOC合作是远远不够的…

【云原生】K8s管理工具--Kubectl详解(一)

一、陈述式管理 1.1、陈述式资源管理方法 kubernetes 集群管理集群资源的唯一入口是通过相应的方法调用 apiserver 的接口kubectl 是官方的 CLI 命令行工具&#xff0c;用于与 apiserver 进行通信&#xff0c;将用户在命令行输入的命令&#xff0c;组织并转化为apiserver 能识…

深度学习之基于Matlab的BP神经网络交通标志识别

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景与意义 随着智能交通系统&#xff08;ITS&#xff09;的快速发展&#xff0c;交通标志识别&#xff0…

十年磨一剑“2024成都电子信息展会”推动电子产业全球发展

2024成都电子展&#xff0c;招商工作已接近尾声&#xff0c;这场盛大的展会不仅是电子信息行业的一次盛会&#xff0c;更是中国西部电子信息产业发展的重要里程碑。自2013年起&#xff0c;中国&#xff08;西部&#xff09;电子信息博览会便选择成都作为其永久的举办地&#xf…

【誉天618·年中钜惠】无忧卡计算VIP会员上线

在数字化浪潮汹涌的当下&#xff0c;技术更新迭代的速度令人目不暇接。为了满足广大技术爱好者与专业人士对于最新技术的渴望与追求。2022年我们推出了誉天系列会员卡&#xff0c;受到了学员和企业的一致好评&#xff0c;现在我们又结合当下的热门ICT技术进行了会员卡升级。 誉…

spring和springboot、springcloud版本关系

进入新公司&#xff0c;看底层框架代码时&#xff0c;想了解spring的版本&#xff0c;很好奇这些版本之间时怎么对应的&#xff0c;因为不同版本应该有依赖关系&#xff0c;用得不对可能代码会有隐藏问题。 Spring、SpringBoot和SpringCloud的版本不一致&#xff0c;并且需要搭…

【Python】 如何对对象列表进行排序,有点意思

在Python中&#xff0c;我们经常需要对对象列表进行排序&#xff0c;这可以通过多种方式实现。当对象是一个自定义类实例时&#xff0c;排序通常基于对象的一个或多个属性。Python提供了内置的sorted()函数和列表的sort()方法&#xff0c;它们都允许我们指定一个排序的关键字。…

一次搞懂常见Banner尺寸,像素标准全解析!

在现代数字营销中&#xff0c;横幅banner广告是一种常见的形式&#xff0c;也是许多网站、博客和在线广告平台上常见的广告类型。然而&#xff0c;正确的横幅banner尺寸是至关重要的&#xff0c;因为它可以影响广告的可见性和效果。在本文中&#xff0c;我们将探讨横幅banner尺…

揭秘:APP广告变现逻辑

APP广告变现项目逻辑 一、项目背景与目标 在当今数字化时代&#xff0c;移动应用&#xff08;APP&#xff09;已成为人们日常生活中不可或缺的一部分。随着智能手机的普及&#xff0c;APP市场呈现出爆炸性增长&#xff0c;为开发者提供了巨大的商业机会。然而&#xff0c;如何在…

线程池(C++)

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 线程池 实现线程类 #pragma once#include <pthread.h> #include <iostream> #include <vector> #include <string> #include <cstdlib> #include <cstring> #include <functional&…

Transformer系列专题(一)——self-attention自注意力机制如何计算

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、总述二、如何计算self-attention三、softmax归一处理Attention整体计算流程 前言 自注意力机制的原理相当于一个词在其上下文中的联系&#xff0c;即将这一…

linux-----环境变量

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言 常见的环境变量&#xff1a; PWD&#xff1a;记录当前工作目录 PATH : 指定命令的搜索路径 HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的…