范围
深度
首先指定深度分析深度,否者会陷入代码海洋之中。
本文只分析到Win32 API/Windows Com组件/STL库函数层次,再下层代码不做探究
本文主要了解QSaveFile及其具体实现,使用到父类数据的地方只讨论关键点
QT Private类
大部分Qt类有一个类名+Private构成的类,这个类主要用于保存数据、具体实现类功能
比如QObject具有QObjectPrivate来实现具体功能,QFile具有QFilePrivate来实现文件读写
这种数据方式是为了更新时不用动导出的头文件,使程序变更Qt版本时不用做任何修改,直接通过编译
QSaveFile
QSaveFile作用
安全写入文件。保证文件要么全部修改,要么没有修改,不会出现只写一部分情况。
用例
#include <QSaveFile>
#include <QByteArray>
#include <QDebug>
int main(int argc, char* argv[])
{
QSaveFile file("D:/1.txt");
if (file.open(QIODevice::WriteOnly))
{
file.write("Hello QFile!");
}
file.commit();
return 0;
}
数据变量
QSaveFile本身没有添加的成员变量,所有成员变量全部继承自父类
QSaveFile中具有来自QObject的成员变量d_ptr,其类型为QObjectData指针,d_ptr指向QObjectPrivate,QObjectPrivate继承自QObjectData。
QSaveFile中d_ptr指向的是QSaveFilePrivate
继承关系
QSaveFile>>QFileDevice>>QIODevice>>QObject
QSaveFilePrivate>>QFileDevicePrivate>>QIODevicePrivate>>QObjectPrivate>>QObjectData
数据变量
QSaveFilePrivate单独具有的变量是QString fileName,代表打开文件路径。其他变量都来自父类
QSaveFile细节分层
QSaveFile领域分层
主要功能函数
QSaveFile::QSaveFile
作用
构造QSaveFile,d_ptr指向new QSaveFilePrivate并设置QSaveFilePrivate::fileName为当前文件
QSaveFile::fileName
作用
获取QSaveFile指向名称
实现原理
实际上就是QSaveFilePrivate::fileName
QSaveFile::setFileName
作用
设置QSaveFile指向名称
实现原理
设置QSaveFilePrivate::fileName为当前文件
QSaveFile::cancelWriting
作用
取消写入文件
调用顺序
QSaveFile::cancelWriting>>QFileDevicePrivate::setError
实现原理
设置写入错误,导致QSaveFile::commit中不替换目标文件
QSaveFile::writeData
作用
将数据写入缓存中。如果超过缓存大小(0x4000),则先将缓存刷新到文件中再数据写入到缓存
实现原理
将数据写入QIODevicePrivate::writeBuffer中
QSaveFile::directWriteFallback
作用
获取QSaveFilePrivate::directWriteFallback的值,默认值为false
实现原理
获取QSaveFilePrivate::directWriteFallback变量
QSaveFile::setDirectWriteFallback
作用
当目标文件目录下无法创建新文件时,设置是否直接写入目标文件。相当于是QFile那种写入,断电时数据只写入一部分。默认值为false
实现原理
设置QSaveFilePrivate::directWriteFallback变量
QSaveFile::open
作用
如果当前目标文件目录能够创建新文件,则创建命名为“目标文件名+随机值”的文件。如果目标文件目录不能创建新文件,并且通过QSaveFile::setDirectWriteFallback设置QSaveFilePrivate::directWriteFallback为true,则直接打开目标文件写入数据。
调用顺序
QSaveFilePrivate::directWriteFallback为默认值false时并且目标文件夹目录可创建新文件。
QSaveFile::Open>>QTemporaryFileEngine::open>>QTemporaryFileName::generateNext>>std::generate>>CreateFile>>QFileDevice::open>>QFileInfo::permissions>>GetFileAttributesEx>>QFileDevice::setPermissions>>QFSFileEngine::setPermissions>>QFileSystemEngine::setPermissions>>_wchmod
实现原理
使用std::generate生成随机字符串加在目标文件名称后,比如目标文件名称D:/1.txt,生成随机字符串eFYrqV,则临时文件名为D:/1.txt.eFYrqV。
再用CreateFile创建D:/1.txt.eFYrqV,如果创建失败分2种情况:
- D:/1.txt.eFYrqV已经存在则再生成新的临时文件。
- 目标文件目录无创建文件权限则回退校验QSaveFilePrivate::directWriteFallback是否为true,如果为true则直接打开目标文件写入。
创建临时文件成功后利用GetFileAttributesEx读取目标文件权限等属性并用_wchmod赋值给新创建的临时文件
QSaveFile::commit
作用
将目标文件替换为临时文件
调用顺序
QSaveFile::commit>>QFileDevice::close>>QFileDevice::flush>>WriteFile>>fflush>>QFSFileEngine::syncToDisk>>QFSFileEnginePrivate::nativeSyncToDisk>>FlushFileBuffers>>QTemporaryFileEngine::renameOverwrite>>QFSFileEngine::renameOverwrite>>QFileSystemEngine::renameOverwriteFile>>MoveFileEx
实现原理
首先利用WriteFile将QIODevicePrivate::writeBuffer写到文件中,并利用fflush刷新缓存到磁盘。文章来源:https://www.toymoban.com/news/detail-434980.html
最后利用MoveFileEx将目标文件替换为临时文件文章来源地址https://www.toymoban.com/news/detail-434980.html
到了这里,关于Qt文件系统源码分析—第二篇QSaveFile的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!