Qt流缓冲的刷新时间小解

2024-01-28 19:58
文章标签 qt 刷新 时间 缓冲 小解

本文主要是介绍Qt流缓冲的刷新时间小解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

今天用QTextStream时候遇到了点点小问题,就是在写入的时候,发现移动文件指针不会覆盖后面的数据。今天一天的时间基本上都放在了这个问题上面,下面具体说说。

例如下面的例子

QFile file(“c:/1.txt”);

QTextStream text(&file);

file.open(QFile::Write);

text<<”1”<<”2”;

text.device().seek(0);

text<<”3”;

其它代码略。下面执行了下面的代码后,文件显示的内容为:123,而不是我们希望的32,这说明了seek(0)并没有移动了文件指针,这到底是怎么回事呢?又如下面的代码

QFile file(“c:/2.txt”);

QTextStream text(&file);

file.open(QFile::Read);

QString str;

text>>Str;

qDebug()<<str;

text.device().seek(0);

str.clear();

str=text.readAll();

qDebug()<<str;

执行后会发现并不是想象的那样,输出了第一行的字符串后,输出余下的,而是输出了余下的后,再输出全部的内容,这又是怎么回事呢?

写了一下午和晚上的代码进行反复的验证,下面是得出的结论:

首先,对于QTextStream类来说,该类有个BUFFER,就是缓冲区,当我们向它绑定的IOdevice写入或者读取数据时候,不会直接操作device,而是操作缓冲区,这样做有个好处,避免频繁的写入硬盘,毕竟内存的速度比硬盘快多了。Qt就是这样,QTextStream会将数据先存入缓冲区,在缓冲区操作,从而节省了系统资源。如第一个例子,text绑定了1.txt,第一个写入语句并没有直接把内容写入文件中,而是写入了内存中的缓冲区,当然缓冲区有大小,大于某大小后,或者主动进行刷新时候,会将数据写入文件,但是我们的例子内容很少,所以都会读入缓冲区,执行seek时候,file的文件指针的确是移动了,移动到了首行,然后再一次的写入数据到了缓冲区,当主函数执行完毕时候,打开文件,内容是123,下面我们把seek参数改为2(用字为单位),再次执行主函数,会发现文件的内容变成了空格123,所以可以得出一个结论,seek是有效的,但是因为实际写入数据的时刻在seek之后,所以无法满足我们原先的设想。

想实现原先的设想,我们可以直接操作file,所有的操作都是即时的,不受缓冲区刷新的影响。另外,我们可以主动的去刷新缓冲区,在所有<<操作符后加一个<<flush;主动去刷新缓冲区,这样就可以直接把数据写入对象中。

对于第二个例子,其实原理跟第一个差不多。当要读取某个文件时候,当文件的大小小于缓冲区大小限额时候,会将数据全部都读取到缓冲区,并将devicepos到最后,每次通过流来读取文件内容的时候,其实都在缓冲区进行操作,那么我们设置指针其实都与缓冲区无关,因为数据的读取在缓冲区而已。而在读取了一个字符串(数据是一行一行的)之后,我们用了seek(0)函数,之后执行readAll()发现数据是余下的数据和原先的文件中的所有数据,这是为什么呢?

因为缓冲区有一个大小的限额,假如文件太大的话,会先读入一部分到缓冲区,然后设置devicepos为那最后部分,内存中的内容读完后,会返回到原先设置的pos,然后继续读取。明白了这个后,我们就可以很容易的明白为什么会输出那些奇怪的东西了。因为文件实在是太小了,所以全部的读入了内存缓冲区,然后先将第一行的字符串输出到str,同时缓冲区也有一个pos,设置到了第一行的字符串的末尾,末尾还有一个回车。执行readAll()函数时候,会将缓冲区的所有的内容全部输出,也就是回车加上缓冲区的所有内容。那么怎么会出现此文件的全部内容呢?答案是我们设置的seek(0),因为当文件太大的时候不能一次性的读入内存缓冲区,剩下的数据该怎么办?所以会去查找devicepos,看是否到了结尾,正常情况下是到结尾的,有2两种情况:

1.文件能够全部读入内存缓冲区

这个情况很简单,全部读入后直接将pos设置为结尾,这样当readAll()后发现已经到了文件结尾了,结束函数,返回正常值。

2.文件不能全部读入内存缓冲区

这个情况也很简单,读取一部分,并将pos设置为截断的部分,readAll()后发现文件没到结尾,继续读入缓冲区,并输出,直到到了文件结尾。

我们的情况则是读取过程中认为的执行了seek(0),即改变了对象自动设置的pos,这样,当pos检测是否到文件结尾时候,会发现没有到!所以又一次的将文件内容全部读到缓冲区并且输出,所以才会又输出了一次全部内容,然后pos发现到了文件结尾,结束函数。

这样,两个问题都解决了。当然个人能力有限,无法完全明白QIODevice的源码,只能不断的写代码进行测试。另外发现QDataStream输入到Device一次后,就会自动刷新,不用人工去刷新,其实我这个问题是看GUI with QT4TCP部分发现的。

 

 

今天又发现,假如使用QTextStream的pos()函数,会根据device重置流的位置和device的位置,然后清空流。而直接操作device的pos函数直接返回了当前的位置,不会进行任何操作。

这篇关于Qt流缓冲的刷新时间小解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/654641

相关文章

Qt QCustomPlot库简介(最新推荐)

《QtQCustomPlot库简介(最新推荐)》QCustomPlot是一款基于Qt的高性能C++绘图库,专为二维数据可视化设计,它具有轻量级、实时处理百万级数据和多图层支持等特点,适用于科学计算、... 目录核心特性概览核心组件解析1.绘图核心 (QCustomPlot类)2.数据容器 (QCPDataC

Golang如何对cron进行二次封装实现指定时间执行定时任务

《Golang如何对cron进行二次封装实现指定时间执行定时任务》:本文主要介绍Golang如何对cron进行二次封装实现指定时间执行定时任务问题,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录背景cron库下载代码示例【1】结构体定义【2】定时任务开启【3】使用示例【4】控制台输出总结背景

Qt如何实现文本编辑器光标高亮技术

《Qt如何实现文本编辑器光标高亮技术》这篇文章主要为大家详细介绍了Qt如何实现文本编辑器光标高亮技术,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以了解下... 目录实现代码函数作用概述代码详解 + 注释使用 QTextEdit 的高亮技术(重点)总结用到的关键技术点应用场景举例示例优化建议

Qt 设置软件版本信息的实现

《Qt设置软件版本信息的实现》本文介绍了Qt项目中设置版本信息的三种常用方法,包括.pro文件和version.rc配置、CMakeLists.txt与version.h.in结合,具有一定的参考... 目录在运行程序期间设置版本信息可以参考VS在 QT 中设置软件版本信息的几种方法方法一:通过 .pro

C++ 函数 strftime 和时间格式示例详解

《C++函数strftime和时间格式示例详解》strftime是C/C++标准库中用于格式化日期和时间的函数,定义在ctime头文件中,它将tm结构体中的时间信息转换为指定格式的字符串,是处理... 目录C++ 函数 strftipythonme 详解一、函数原型二、功能描述三、格式字符串说明四、返回值五

从基础到进阶详解Pandas时间数据处理指南

《从基础到进阶详解Pandas时间数据处理指南》Pandas构建了完整的时间数据处理生态,核心由四个基础类构成,Timestamp,DatetimeIndex,Period和Timedelta,下面我... 目录1. 时间数据类型与基础操作1.1 核心时间对象体系1.2 时间数据生成技巧2. 时间索引与数据

VS配置好Qt环境之后但无法打开ui界面的问题解决

《VS配置好Qt环境之后但无法打开ui界面的问题解决》本文主要介绍了VS配置好Qt环境之后但无法打开ui界面的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要... 目UKeLvb录找到Qt安装目录中designer.UKeLvBexe的路径找到vs中的解决方案资源

SpringCloud使用Nacos 配置中心实现配置自动刷新功能使用

《SpringCloud使用Nacos配置中心实现配置自动刷新功能使用》SpringCloud项目中使用Nacos作为配置中心可以方便开发及运维人员随时查看配置信息,及配置共享,并且Nacos支持配... 目录前言一、Nacos中集中配置方式?二、使用步骤1.使用$Value 注解2.使用@Configur

利用Python实现时间序列动量策略

《利用Python实现时间序列动量策略》时间序列动量策略作为量化交易领域中最为持久且被深入研究的策略类型之一,其核心理念相对简明:对于显示上升趋势的资产建立多头头寸,对于呈现下降趋势的资产建立空头头寸... 目录引言传统策略面临的风险管理挑战波动率调整机制:实现风险标准化策略实施的技术细节波动率调整的战略价

Qt之QMessageBox的具体使用

《Qt之QMessageBox的具体使用》本文介绍Qt中QMessageBox类的使用,用于弹出提示、警告、错误等模态对话框,具有一定的参考价值,感兴趣的可以了解一下... 目录1.引言2.简单介绍3.常见函数4.按钮类型(QMessage::StandardButton)5.分步骤实现弹窗6.总结1.引言