Qt文件系统源码分析—第二篇QSaveFile

这篇具有很好参考价值的文章主要介绍了Qt文件系统源码分析—第二篇QSaveFile。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

范围

深度

首先指定深度分析深度,否者会陷入代码海洋之中。

本文只分析到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细节分层

Qt文件系统源码分析—第二篇QSaveFile

QSaveFile领域分层

Qt文件系统源码分析—第二篇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种情况:

  1. D:/1.txt.eFYrqV已经存在则再生成新的临时文件。
  2. 目标文件目录无创建文件权限则回退校验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

实现原理

首先利用WriteFileQIODevicePrivate::writeBuffer写到文件中,并利用fflush刷新缓存到磁盘。

最后利用MoveFileEx将目标文件替换为临时文件文章来源地址https://www.toymoban.com/news/detail-434980.html

到了这里,关于Qt文件系统源码分析—第二篇QSaveFile的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于React实现无限滚动的日历详细教程,附源码【手写日历教程第二篇】

    最常见的日历大部分都是滚动去加载更多的月份,而不是让用户手动点击按钮切换日历月份。滚动加载的交互方式对于用户而言是更加丝滑和舒适的,没有明显的操作割裂感。 那么现在需要做一个这样的无限滚动的日历,前端开发者应该如何去思考和代码实现呢?下面我会详

    2024年02月11日
    浏览(23)
  • JVM第二篇 类加载子系统

    JVM主要包含两个模块,类加载子系统和执行引擎,本篇博客将类加载子系统做一下梳理总结。 目录 1. 类加载子系统功能 2. 类加载子系统执行过程 2.1 加载 2.2 链接  2.3 初始化  3. 类加载器分类  3.1 引导类加载器  3.2 自定义加载器  3.2.1 自定义加载器实现步骤​编辑  4. 类加

    2024年02月11日
    浏览(31)
  • MySQL数据库进阶第二篇(索引,SQL性能分析,使用规则)

    本篇博客深入详细地介绍了数据库索引的概念和重要性。内容包含:索引的概念和目标、索引的优点与缺点。此外,博客还深入解析了三种主要的索引结构:B-Tree、B+Tree和Hash,提供了详细的结构解析和优化方法,并通过插图进一步增强了理解。 博客的部分内容专注于对B-Tr

    2024年02月21日
    浏览(42)
  • 【微信小程序丨第二篇】小程序的基本目录结构与文件作用剖析

    小程序框架的⽬标是通过尽可能简单、⾼效的⽅式让开发者可以在微信中开发具有原⽣APP体验的服务。 ⼩程序框架提供了⾃⼰的视图层描述语⾔ WXML 和 WXSS ,以及 JavaScript ,并 在视图层与逻辑层间提供了数据传输和事件系统 ,让开发者能够专注于数据与逻辑。 传统web 微信

    2024年02月09日
    浏览(29)
  • 【计算机三级网络技术】 第二篇 中小型系统总体规划与设计

    基于网络的信息系统结构应包括 网络运行环境、网络系统、网络操作系统。 网络运行环境指为了保障网络系统安全、可靠与正常运行所需的基本设施和设备条件,主要包括 机房与电源 两部分。 (1)机房和设备间、配线间。 机房用于放置交换机、核心路由器、服务器等核心

    2024年02月09日
    浏览(35)
  • xv6(RISC-V)操作系统源码分析第二节——操作系统组织

    一个操作系统至少需要满足以下三个要求: 多路复用 进程隔离 进程通信 硬件CPU的数量有限,且往往少于同时存在的进程数量。而操作系统需要支持进程的并发执行,所以操作系统应该能使多个进程分时共享计算机的资源。 一个进程的运行,应当具有一定的独立性,这个独

    2024年02月03日
    浏览(34)
  • Java项目实战笔记--基于SpringBoot3.0开发仿12306高并发售票系统--(二)项目实现-第二篇-前端模块搭建及单点登录的实现

    本文参考自 Springboot3+微服务实战12306高性能售票系统 - 慕课网 (imooc.com) 本文是仿12306项目实战第(二)章——项目实现 的第二篇,详细讲解使用Vue3 + Vue CLI 实现前端模块搭建的过程,同时其中也会涉及一些前后端交互的实现,因此也会开发一些后端接口;搭建好前端页面后,

    2024年03月26日
    浏览(42)
  • Spring篇---第二篇

    一、构造器注入 将被依赖对象通过构造函数的参数注入给依赖对象,并且在初始化对象的时候注 入。 优点: 对象初始化完成后便可获得可使用的对象。 缺点: 当需要注入的对象很多时,构造器参数列表将会很长; 不够灵活。若有多种注入方式,每种 方式只需注入指定几

    2024年02月07日
    浏览(33)
  • Vue基础第二篇

    总结: 1 写在data或method中的属性或方法,从vm中直接可以 . 出来 2 methods的函数中,如果想使用data或methods中的属性,直接this.名字  就可以了 示例: 总结: 1  v-on:事件名=\\\'函数\\\'-----》简写成  @事件名=\\\'函数\\\' 2 触发函数,可以传参数 示例: 标签上   name   id  class  src  href

    2024年02月08日
    浏览(34)
  • 初识Linux篇:第二篇

    😁👉本篇主要介绍Linux的一些指令的应用👈 在学习Linux的基本指令之前,让我们先详细的认识一下 操作系统和命令行的概念 ; 🤔什么是操作系统(OS)呢? 操作系统是一款进行 软件资源与硬件管理 的 软件 ; 🤔🤔那么操作系统在计算机软硬件体系结构中大概在什么位置呢

    2024年02月04日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包