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并列)的更多相关文章

  1. java使用类序列化反序列化(读写文件)

    创建类:Role package com.wbg.springRedis.entity; import java.io.Serializable; public class Role implemen ...

  2. MFC CFile类读写文件详解

    CFile类提供了对文件进行打开,关闭,读,写,删除,重命名以及获取文件信息等文件操作的基本功能,足以处理任意类型的文件操作. 一个读写文件的例子: 文件I/O 虽然使用CArchive类内建的序列化 ...

  3. JAVA基础学习之流的简述及演示案例、用缓冲区方法buffer读写文件、File类对象的使用、Serializable标记接口(6)

    1.流的简述及演示案例输入流和输出流相对于内存设备而言.将外设中的数据读取到内存中:输入将内存的数写入到外设中:输出.字符流的由来:其实就是:字节流读取文字字节数据后,不直接操作而是先查指定的编码表. ...

  4. Commons IO方便读写文件的工具类

    Commons IO是apache的一个开源的工具包,封装了IO操作的相关类,使用Commons IO可以很方便的读写文件,url源代码等. 普通地读取一个网页的源代码的代码可能如下 InputStr ...

  5. 从用python自动生成.h的头文件集合和类声明集合到用python读写文件

    最近在用python自动生成c++的类.因为这些类会根据需求不同产生不同的类,所以需要用python自动生成.由于会产生大量的类,而且这些类是变化的.所以如果是在某个.h中要用include来加载这些 ...

  6. RandomAccessFile类——高效快捷地读写文件

    RandomAceessFile类 RandomAccessFile类是一个专门读写文件的类,封装了基本的IO流,在读写文件内容方面比常规IO流更方便.更灵活.但也仅限于读写文件,无法像IO流一样,可 ...

  7. c++builder 读写文件类

    c++builder 读写文件类 TStreamReader.TStreamWriter读取一行 http://docwiki.embarcadero.com/CodeExamples/XE8/en/ ...

  8. 01.使用File类读写文件

    使用File类去读数据: 方法一:使用ReadAllBytes(); 方法 namespace _01.使用File类读写数据01 { class Program { static void Main ...

  9. c# 命令行下编译c#文件 // c# file类读写文件

    c# 命令行下编译c#文件 2010-03-01 15:02:14|  分类: c# 学习|字号 订阅     在 开始  ——>程序 ——>vstool中打开vs2008命令提示. 通过 ...

随机推荐

  1. Jenkins自动化打包(Gitlab)并上传蒲公英

    整个过程详见:https://www.jianshu.com/p/91e8f571fc2b 以下是遇到的问题及解决过程 一.安装homebrew(网速很慢很慢……被墙了) /usr/bin/ruby ...

  2. 在CentOS7中安装zookeeper

    参考:https://www.linuxidc.com/Linux/2016-09/135052.htm 1.zookeeper运行需要jdk环境,先确保有配置jdk,可以参考此处 2.下载解压zoo ...

  3. delphi 解决android 9上无法使用http协议

    delphi 解决android 9上无法使用http协议 安卓9不让客户端通过非https方式访问服务端数据(不允许发送明文http请求)的问题. 解决方法: 1.选择安卓平台编译一次程序,在项目根 ...

  4. Python - celery 相关报错 - AttributeError: type object '_multiprocessing.win32' has no attribute 'WAIT_OBJECT_0'

    报错场景 执行   celery worker -A tasks -l INFO  打开 worker 的时候报错无法进行 报错解决 Celery 的版本过高, 进行降级处理即可 pip instal ...

  5. 复制粘贴引发的鸠占鹊巢——IDEA复制项目导致sources root复用了另一个项目

    复制粘贴大法一向是程序猿的利器,但有时也会引发一些拎不清的麻烦关系来.比如我们现在想新建一个项目,为了快速而对原来的uis-gateway动用了复制粘贴大法,然后改改项目名就成了uis-applica ...

  6. MySQL复制线程状态转变

    一.主库线程状态(State)值 以下列表显示了主从复制中主服务器的Binlog Dump线程的State列中可能看到的最常见状态(SHOW PROCESSLIST).如果Binlog Dump线程在 ...

  7. linux简单命令2---文件搜索命令

    1:文件搜索命令:locate 文件名搜索速度快,缺点不能复杂的搜索.在数据库(/var/lib/mlocate)查找.它是一天一更新.可以强制更新数据库:updatedb 2:搜索命令的命令:whe ...

  8. (九)UML之活动图

    一.概念 二. 在Rational rose 中画活动图 2.1 创建Activity Diagram 2.2 画图

  9. laravel console handle 传参方法

    <?php namespace App\Console\Commands; use Illuminate\Console\Command; use App\Libs\wxpay\CLogFile ...

  10. Java多线程——线程池使用示例

    示例代码: import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public cla ...