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开发一个简单的OFD阅读器

《基于Qt开发一个简单的OFD阅读器》这篇文章主要为大家详细介绍了如何使用Qt框架开发一个功能强大且性能优异的OFD阅读器,文中的示例代码讲解详细,有需要的小伙伴可以参考一下... 目录摘要引言一、OFD文件格式解析二、文档结构解析三、页面渲染四、用户交互五、性能优化六、示例代码七、未来发展方向八、结论摘要

如何用Java结合经纬度位置计算目标点的日出日落时间详解

《如何用Java结合经纬度位置计算目标点的日出日落时间详解》这篇文章主详细讲解了如何基于目标点的经纬度计算日出日落时间,提供了在线API和Java库两种计算方法,并通过实际案例展示了其应用,需要的朋友... 目录前言一、应用示例1、天安门升旗时间2、湖南省日出日落信息二、Java日出日落计算1、在线API2

如何使用 Bash 脚本中的time命令来统计命令执行时间(中英双语)

《如何使用Bash脚本中的time命令来统计命令执行时间(中英双语)》本文介绍了如何在Bash脚本中使用`time`命令来测量命令执行时间,包括`real`、`user`和`sys`三个时间指标,... 使用 Bash 脚本中的 time 命令来统计命令执行时间在日常的开发和运维过程中,性能监控和优化是不

python中的与时间相关的模块应用场景分析

《python中的与时间相关的模块应用场景分析》本文介绍了Python中与时间相关的几个重要模块:`time`、`datetime`、`calendar`、`timeit`、`pytz`和`dateu... 目录1. time 模块2. datetime 模块3. calendar 模块4. timeit

python与QT联合的详细步骤记录

《python与QT联合的详细步骤记录》:本文主要介绍python与QT联合的详细步骤,文章还展示了如何在Python中调用QT的.ui文件来实现GUI界面,并介绍了多窗口的应用,文中通过代码介绍... 目录一、文章简介二、安装pyqt5三、GUI页面设计四、python的使用python文件创建pytho

Java将时间戳转换为Date对象的方法小结

《Java将时间戳转换为Date对象的方法小结》在Java编程中,处理日期和时间是一个常见需求,特别是在处理网络通信或者数据库操作时,本文主要为大家整理了Java中将时间戳转换为Date对象的方法... 目录1. 理解时间戳2. Date 类的构造函数3. 转换示例4. 处理可能的异常5. 考虑时区问题6.

QT实现TCP客户端自动连接

《QT实现TCP客户端自动连接》这篇文章主要为大家详细介绍了QT中一个TCP客户端自动连接的测试模型,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录版本 1:没有取消按钮 测试效果测试代码版本 2:有取消按钮测试效果测试代码版本 1:没有取消按钮 测试效果缺陷:无法手动停

基于Qt实现系统主题感知功能

《基于Qt实现系统主题感知功能》在现代桌面应用程序开发中,系统主题感知是一项重要的功能,它使得应用程序能够根据用户的系统主题设置(如深色模式或浅色模式)自动调整其外观,Qt作为一个跨平台的C++图形用... 目录【正文开始】一、使用效果二、系统主题感知助手类(SystemThemeHelper)三、实现细节

Qt实现文件的压缩和解压缩操作

《Qt实现文件的压缩和解压缩操作》这篇文章主要为大家详细介绍了如何使用Qt库中的QZipReader和QZipWriter实现文件的压缩和解压缩功能,文中的示例代码简洁易懂,需要的可以参考一下... 目录一、实现方式二、具体步骤1、在.pro文件中添加模块gui-private2、通过QObject方式创建

Qt QWidget实现图片旋转动画

《QtQWidget实现图片旋转动画》这篇文章主要为大家详细介绍了如何使用了Qt和QWidget实现图片旋转动画效果,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 一、效果展示二、源码分享本例程通过QGraphicsView实现svg格式图片旋转。.hpjavascript