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

相关文章

服务器集群同步时间手记

1.时间服务器配置(必须root用户) (1)检查ntp是否安装 [root@node1 桌面]# rpm -qa|grep ntpntp-4.2.6p5-10.el6.centos.x86_64fontpackages-filesystem-1.41-1.1.el6.noarchntpdate-4.2.6p5-10.el6.centos.x86_64 (2)修改ntp配置文件 [r

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

MiniGPT-3D, 首个高效的3D点云大语言模型,仅需一张RTX3090显卡,训练一天时间,已开源

项目主页:https://tangyuan96.github.io/minigpt_3d_project_page/ 代码:https://github.com/TangYuan96/MiniGPT-3D 论文:https://arxiv.org/pdf/2405.01413 MiniGPT-3D在多个任务上取得了SoTA,被ACM MM2024接收,只拥有47.8M的可训练参数,在一张RTX

批处理以当前时间为文件名创建文件

批处理以当前时间为文件名创建文件 批处理创建空文件 有时候,需要创建以当前时间命名的文件,手动输入当然可以,但是有更省心的方法吗? 假设我是 windows 操作系统,打开命令行。 输入以下命令试试: echo %date:~0,4%_%date:~5,2%_%date:~8,2%_%time:~0,2%_%time:~3,2%_%time:~6,2% 输出类似: 2019_06

【QT】基础入门学习

文章目录 浅析Qt应用程序的主函数使用qDebug()函数常用快捷键Qt 编码风格信号槽连接模型实现方案 信号和槽的工作机制Qt对象树机制 浅析Qt应用程序的主函数 #include "mywindow.h"#include <QApplication>// 程序的入口int main(int argc, char *argv[]){// argc是命令行参数个数,argv是

【MRI基础】TR 和 TE 时间概念

重复时间 (TR) 磁共振成像 (MRI) 中的 TR(重复时间,repetition time)是施加于同一切片的连续脉冲序列之间的时间间隔。具体而言,TR 是施加一个 RF(射频)脉冲与施加下一个 RF 脉冲之间的持续时间。TR 以毫秒 (ms) 为单位,主要控制后续脉冲之前的纵向弛豫程度(T1 弛豫),使其成为显著影响 MRI 中的图像对比度和信号特性的重要参数。 回声时间 (TE)

Python QT实现A-star寻路算法

目录 1、界面使用方法 2、注意事项 3、补充说明 用Qt5搭建一个图形化测试寻路算法的测试环境。 1、界面使用方法 设定起点: 鼠标左键双击,设定红色的起点。左键双击设定起点,用红色标记。 设定终点: 鼠标右键双击,设定蓝色的终点。右键双击设定终点,用蓝色标记。 设置障碍点: 鼠标左键或者右键按着不放,拖动可以设置黑色的障碍点。按住左键或右键并拖动,设置一系列黑色障碍点

使用Qt编程QtNetwork无法使用

使用 VS 构建 Qt 项目时 QtNetwork 无法使用的问题 - 摘叶飞镖 - 博客园 (cnblogs.com) 另外,强烈建议在使用QNetworkAccessManager之前看看这篇文章: Qt 之 QNetworkAccessManager踏坑记录-CSDN博客 C++ Qt开发:QNetworkAccessManager网络接口组件 阅读目录 1.1 通用API函数

LeetCode:64. 最大正方形 动态规划 时间复杂度O(nm)

64. 最大正方形 题目链接 题目描述 给定一个由 0 和 1 组成的二维矩阵,找出只包含 1 的最大正方形,并返回其面积。 示例1: 输入: 1 0 1 0 01 0 1 1 11 1 1 1 11 0 0 1 0输出: 4 示例2: 输入: 0 1 1 0 01 1 1 1 11 1 1 1 11 1 1 1 1输出: 9 解题思路 这道题的思路是使用动态规划

O(n)时间内对[0..n^-1]之间的n个数排序

题目 如何在O(n)时间内,对0到n^2-1之间的n个整数进行排序 思路 把整数转换为n进制再排序,每个数有两位,每位的取值范围是[0..n-1],再进行基数排序 代码 #include <iostream>#include <cmath>using namespace std;int n, radix, length_A, digit = 2;void Print(int *A,