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

相关文章

Python的Darts库实现时间序列预测

《Python的Darts库实现时间序列预测》Darts一个集统计、机器学习与深度学习模型于一体的Python时间序列预测库,本文主要介绍了Python的Darts库实现时间序列预测,感兴趣的可以了解... 目录目录一、什么是 Darts?二、安装与基本配置安装 Darts导入基础模块三、时间序列数据结构与

MyBatis Plus实现时间字段自动填充的完整方案

《MyBatisPlus实现时间字段自动填充的完整方案》在日常开发中,我们经常需要记录数据的创建时间和更新时间,传统的做法是在每次插入或更新操作时手动设置这些时间字段,这种方式不仅繁琐,还容易遗漏,... 目录前言解决目标技术栈实现步骤1. 实体类注解配置2. 创建元数据处理器3. 服务层代码优化填充机制详

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

QT Creator配置Kit的实现示例

《QTCreator配置Kit的实现示例》本文主要介绍了使用Qt5.12.12与VS2022时,因MSVC编译器版本不匹配及WindowsSDK缺失导致配置错误的问题解决,感兴趣的可以了解一下... 目录0、背景:qt5.12.12+vs2022一、症状:二、原因:(可以跳过,直奔后面的解决方法)三、解决方

C# LiteDB处理时间序列数据的高性能解决方案

《C#LiteDB处理时间序列数据的高性能解决方案》LiteDB作为.NET生态下的轻量级嵌入式NoSQL数据库,一直是时间序列处理的优选方案,本文将为大家大家简单介绍一下LiteDB处理时间序列数... 目录为什么选择LiteDB处理时间序列数据第一章:LiteDB时间序列数据模型设计1.1 核心设计原则

MySQL按时间维度对亿级数据表进行平滑分表

《MySQL按时间维度对亿级数据表进行平滑分表》本文将以一个真实的4亿数据表分表案例为基础,详细介绍如何在不影响线上业务的情况下,完成按时间维度分表的完整过程,感兴趣的小伙伴可以了解一下... 目录引言一、为什么我们需要分表1.1 单表数据量过大的问题1.2 分表方案选型二、分表前的准备工作2.1 数据评估

MySQL中DATE_FORMAT时间函数的使用小结

《MySQL中DATE_FORMAT时间函数的使用小结》本文主要介绍了MySQL中DATE_FORMAT时间函数的使用小结,用于格式化日期/时间字段,可提取年月、统计月份数据、精确到天,对大家的学习或... 目录前言DATE_FORMAT时间函数总结前言mysql可以使用DATE_FORMAT获取日期字段

Qt中实现多线程导出数据功能的四种方式小结

《Qt中实现多线程导出数据功能的四种方式小结》在以往的项目开发中,在很多地方用到了多线程,本文将记录下在Qt开发中用到的多线程技术实现方法,以导出指定范围的数字到txt文件为例,展示多线程不同的实现方... 目录前言导出文件的示例工具类QThreadQObject的moveToThread方法实现多线程QC

Python标准库datetime模块日期和时间数据类型解读

《Python标准库datetime模块日期和时间数据类型解读》文章介绍Python中datetime模块的date、time、datetime类,用于处理日期、时间及日期时间结合体,通过属性获取时间... 目录Datetime常用类日期date类型使用时间 time 类型使用日期和时间的结合体–日期时间(

Java获取当前时间String类型和Date类型方式

《Java获取当前时间String类型和Date类型方式》:本文主要介绍Java获取当前时间String类型和Date类型方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录Java获取当前时间String和Date类型String类型和Date类型输出结果总结Java获取