使用QSaveFile类安全的读写文件(继承自QFileDevice,与QFile并列)
QSaveFile类也是一种I/O设备,来用来读写文本文件和二进制文件,但使用该类的话,在写入操作失败时不会导致已经存在的数据丢失。
该类在执行写操作时,会先将内容写入到一个临时文件中,如果没有错误发生,我们可以在最后调用其成员函数commit()来将临时文件中的内容移到目标文件中。这能确保目标文件中的数据在写操作发生错误时不会丢失数据,也不会出现部分写入的情况。所以,一般使用QSaveFile类向磁盘上保存整份文档。
QSaveFile会自动的检测写入过程中所出现的错误,例如无法写入全部的数据。它会记得有错误发生,并在commit()时放弃临时文件。
至于该类的使用,和QFile类似,使用open()函数打开文件,使用QDataStream或QTextStream类进行读写,也可以使用从QIODevice继承的函数read(),readLine(),write()等。但不同的是,不能调用close()函数,而应该调用commit()函数。如果没有调用commit()函数,则QSaveFile对象销毁时,会丢弃临时文件。
当然,当应用程序出错时,我们也可以主动放弃写入的数据,只要调用cancelWriting()即可,这样,即使以后又调用了commit(),也不会发生真正的保存文件操作。
使用该类,我们也可以跳过临时文件,直接将数据写入到目标文件中。上面我们说过,QSaveFile类会在和目标文件的同一目录下创建一个临时文件,并自动的进行重命名。但如果该目录的权限限制不允许创建文件呢。通常,在这种情况下,open()调用会失败。而为了解决这个问题,即能让用户编辑一个现存的文件,而不创建新文件,可以调用setDirectWriteFallback(),为其传入true,这样,在接下来调用open()时就会退回到直接打开目标文件,并向其写入数据,而不会使用一个临时文件。但这也会失去QSaveFile提供的原子保证功能,即在写入出错的情况下,可能会导致部分写入的情况,并且会使cancelWriting()函数失效。
下面,我们使用一个例子来使用以下该类。
新建一个Qt控制台程序,代码如下:
#include <QCoreApplication>
#include <QSaveFile>
#include <QFile>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QFile file("test.txt");
//QSaveFile file("test.txt");
if(!file.open(QIODevice::WriteOnly))
{
return 0;
}
int i = 1;
while(1)
{
QString str = QString("hello %1\n").arg(i++);
file.write(str.toLocal8Bit());
qDebug() << str;
}
return a.exec();
}
我们使用一个死循环往一个文件中写数据,如果我们在循环的过程中,直接退出程序,对于这种情况,如果我们使用的是QFile类,那么将会在磁盘上产生一个test.txt文件,里面存储的是程序退出前所写入的内容。如下:
而如果我们使用QSaveFile,那么将不会在磁盘上生成目标文件test.txt,而是会将这些数据存储到所生成的一个临时文件中:如下:
---------------------
作者:求道玉
来源:CSDN
原文:https://blog.csdn.net/Amnes1a/article/details/69942057
版权声明:本文为博主原创文章,转载请附上博文链接!
使用QSaveFile类安全的读写文件(继承自QFileDevice,与QFile并列)的更多相关文章
- java使用类序列化反序列化(读写文件)
创建类:Role package com.wbg.springRedis.entity; import java.io.Serializable; public class Role implemen ...
- MFC CFile类读写文件详解
CFile类提供了对文件进行打开,关闭,读,写,删除,重命名以及获取文件信息等文件操作的基本功能,足以处理任意类型的文件操作. 一个读写文件的例子: 文件I/O 虽然使用CArchive类内建的序列化 ...
- JAVA基础学习之流的简述及演示案例、用缓冲区方法buffer读写文件、File类对象的使用、Serializable标记接口(6)
1.流的简述及演示案例输入流和输出流相对于内存设备而言.将外设中的数据读取到内存中:输入将内存的数写入到外设中:输出.字符流的由来:其实就是:字节流读取文字字节数据后,不直接操作而是先查指定的编码表. ...
- Commons IO方便读写文件的工具类
Commons IO是apache的一个开源的工具包,封装了IO操作的相关类,使用Commons IO可以很方便的读写文件,url源代码等. 普通地读取一个网页的源代码的代码可能如下 InputStr ...
- 从用python自动生成.h的头文件集合和类声明集合到用python读写文件
最近在用python自动生成c++的类.因为这些类会根据需求不同产生不同的类,所以需要用python自动生成.由于会产生大量的类,而且这些类是变化的.所以如果是在某个.h中要用include来加载这些 ...
- RandomAccessFile类——高效快捷地读写文件
RandomAceessFile类 RandomAccessFile类是一个专门读写文件的类,封装了基本的IO流,在读写文件内容方面比常规IO流更方便.更灵活.但也仅限于读写文件,无法像IO流一样,可 ...
- c++builder 读写文件类
c++builder 读写文件类 TStreamReader.TStreamWriter读取一行 http://docwiki.embarcadero.com/CodeExamples/XE8/en/ ...
- 01.使用File类读写文件
使用File类去读数据: 方法一:使用ReadAllBytes(); 方法 namespace _01.使用File类读写数据01 { class Program { static void Main ...
- c# 命令行下编译c#文件 // c# file类读写文件
c# 命令行下编译c#文件 2010-03-01 15:02:14| 分类: c# 学习|字号 订阅 在 开始 ——>程序 ——>vstool中打开vs2008命令提示. 通过 ...
随机推荐
- java读取excel文件数据导入mysql数据库
这是我来公司的第二周的一个小学习任务,下面是实现过程: 1.建立maven工程(方便管理jar包) 在pom.xml导入 jxl,mysql-connector 依赖 可以在maven仓库搜索 2.建 ...
- 走进JavaWeb技术世界16:极简配置的SpringBoot
一位阿里 Java 工程师的技术小站.作者黄小斜,专注 Java 相关技术:SSM.SpringBoot.MySQL.分布式.中间件.集群.Linux.网络.多线程,偶尔讲点Docker.ELK,同时 ...
- Buuctf pwn1 详细wp
目录 程序基本信息 程序溢出点 确定返回地址 编写exp脚本 成功getshell 程序基本信息 我们可以看到这是一个64程序,没有保护开启. 程序溢出点 gets函数可以读取无限字符,存在栈溢出. ...
- JavaScript数字精度丢失的一些问题
本文分为三个部分 JS 数字精度丢失的一些典型问题 JS 数字精度丢失的原因 解决方案(一个对象+一个函数) 一.JS数字精度丢失的一些典型问题 1. 两个简单的浮点数相加 1 0.1 + 0.2 ! ...
- 【Maven】为什么Maven dependencies有的jar包显示为灰色?
因为它们的scope被限制住了,放开就恢复为亮白色. 来两张图片比对一下就清楚了: 没有限制scope,是正常的亮白色. 限制scope为test,显示为灰黑色. 其实颜色不重要,重要的是scope会 ...
- vue-cli项目中使用全局过滤器及传参(日期格式化)
// 过滤日期格式,传入时间戳,根据参数返回不同格式 const formatTimer = function(val, hours) { if (val) { ); var y = dateTime ...
- (十一)Centos之帮助命令
帮助命令man (manual) 比如我们可以看下man命令的解释 [root@localhost ~]# man man MAN(1) ...
- IE和火狐的css兼容性问题
CSS对浏览器器的兼容性具有很高的价值,通常情况下IE和Firefox存在很大的解析差异,这里介绍一下兼容要点. 1.DOCTYPE 影响 CSS 处理 2.FF: div 设置 margin-le ...
- Python3安装后无法使用退格键
解决办法 # 安装readline模块 yum -y install readline-devel # 进入Python安装目录 cd /usr/python/Python-3.7.2 # 重新安装 ...
- Linux配置代理IP
Linux配置代理IP: vim /etc/profile http_proxy=http://username:password@ip:port/ https_proxy=http://userna ...