您现在的位置是:首页 >技术教程 >QFile源码分析网站首页技术教程

QFile源码分析

魂恒 2023-05-24 04:00:02
简介QFile源码分析

1. 深度

首先指定深度分析深度,不然会陷入代码海洋之中。
本文只分析到Win32 API/Windows Com组件层次,再下层代码不做探究
本文主要了解QFile及其具体实现,使用到父类数据的地方只讨论关键点

2. QFile作用

读写文件信息

3. 继承关系

QFile>>QFileDevice>>QIODevice>>QObject

4. 数据变量

QFile本身没有添加的成员变量,所有成员变量全部继承自父类
大部分Qt类有一个类名+Private构成的类,这个类主要用于保存数据、具体实现类功能
比如QObject具有QObjectPrivate来实现具体功能,QFile具有QFilePrivate来实现文件读写
这种数据方式是为了更新时不用动导出的头文件,使程序变更Qt版本时不用做修改,直接编译通过

QFile中具有来自QObject的成员变量d_ptr,其类型为QObjectData指针,d_ptr指向QObjectPrivate,QObjectPrivate继承自QObjectData。
QFile中d_ptr指向的是QFilePrivate

5. QFilePrivate继承关系

QFilePrivate>>QFileDevicePrivate>>QIODevicePrivate>>QObjectPrivate

6. QFilePrivate数据变量

QFilePrivate单独具有的变量是QString fileName,代表打开文件路径。其他变量都来自父类

接下来介绍QFile主要功能函数:

7. 调用顺序

首先介绍下函数通用调用流程
QFile中大部分函数是先调用到QFileDevice中,再创建QFSFileEngine引擎,再由QFSFileEngine实现对应功能

8. QFile::permissions

a. 函数作用
获取文件的权限和所有权
b. 具体实现函数
依靠Win32 API GetFileAttributesEx来获取文件属性,C语言函数_waccess来获取文件读写权限。
_waccess在Windows中也是依靠GetFileAttributesEx实现
c. 调用顺序
QFile::permissions调用QFileDevice::permissions。
QFileDevice::permissions调用QFilePrivate::engine。
QFilePrivate::engine中如果fileEngine指针为空,则调用QAbstractFileEngine::create创建QFSFileEngine,并将fileEngine指向QFSFileEngine
通过fileEngine调用QFSFileEngine::fileFlags
QFSFileEngine::fileFlags调用QFSFileEnginePrivate::doStat
QFSFileEnginePrivate::doStat调用QFileSystemEngine::fillMetaData
QFileSystemEngine::fillMetaData调用Win32 API GetFileAttributesEx来获取文件属性并填充QFSFileEnginePrivate::metaData、QFSFileEnginePrivate::fileEntry信息
依照QFSFileEnginePrivate::metaData、QFSFileEnginePrivate::fileEntry返回权限标识

9. QFile::setPermissions

a. 函数作用
设置文件的权限和所有权
b.  具体实现函数
C语言函数_wchmod修改文件权限,_wchmod依靠Win32 API SetFileAttributesEx设置文件权限
c. 调用顺序
QFile::setPermissions调用QFileDevice::setPermissions
QFileDevice::setPermissions调用QFilePrivate::engine,QFilePrivate::engine作用同上
通过fileEngine调用QFSFileEngine::setPermissions
QFSFileEngine::setPermissions调用QFileSystemEngine::setPermissions
QFileSystemEngine::setPermissions具体由C语言_wchmod实现
_wchmod具体由Win32 API SetFileAttributesEx实现,C语言函数更好跨平台,因此很多地方优先C语言函数

10. QFile::size

a. 函数作用
获取文件大小
b. 具体实现函数
依靠Win32 API GetFileAttributesEx来获取文件属性

11. QFile::copy(const QString &newName)

a. 函数作用
拷贝文件
b. 具体实现
Win32 API CopyFile

12. QFile::exists

a. 函数作用
检查文件是否存在
b. 具体实现
Win32 API GetFileAttributesEx

13. QFile::rename

a. 函数作用
文件重命名
b. 具体实现
Win32 API MoveFile

14. QFile::link

a. 函数作用
创建链接文件
b. 具体实现
通过Com组件,先找到CLSID_ShellLink,再查询到IID_IPersistFile,最后调用IPersistFile::Save创建链接
为什么不用CreateSymbolicLink实现?
CreateSymbolicLink:最低客户端Windows Vista,最低服务器Windows Server 2008
IShellLink:最低客户端Windows XP,最低服务器Windows Server 2000

15. QFile::setFileName

a. 函数作用
更改QFile代表的文件,并不会打开文件
b. 具体实现
关闭之前打开的文件并更改QFilePrivate中保存的文件名称

16. QFile::moveToTrash

a. 函数作用
移动到回收站
b. 具体实现
大于win7
通过Com组件找到CLSID_FileOperation,最后调用IFileOperation::DeleteItem再执行IFileOperation::PerformOperations
小于等于win7:SHFileOperation
为什么不用DeleteFile实现?
DeleteFile最低客户端XP、最低服务器Windows Server 2003,并且无法递归删除目录中的文件、无法删除空目录
IFileOperation最低客户端Windows Vista,最低服务器Windows Server 2008。能删目录和递归删除
SHFileOperation最低客户端XP最低服务器Windows 2000 Server。能删目录和递归删除在Windows Vista版本时已被IFileOperation替代

17. QFile::symLinkTarget

a. 函数作用
返回符号链接指向的路径
b. 具体实现
通过Com组件,先找到CLSID_ShellLink,再查询到IID_IPersistFile,最后调用IShellLink::GetPath获取链接指向的文件全路径

18. QFile::open

a. 函数作用
打开文件
b. 具体实现
Win32 API CreateFile

19. QFile::readAll

a. 函数作用
读取文件中所有数据
b. 具体实现
Win32 API ReadFile

20. QFile::write

a. 函数作用
拷贝文件
b. 具体实现
write只是将buffer放在QIODevicePrivate::writeBuffer,除非内存大于0x4000才会写入文件中

21. QFile::flush

a. 函数作用
将QIODevicePrivate::writeBuffer中数据写入到文件中
b. 具体实现
Win32 API WriteFile和fflush

22. QFile::remove

a. 函数作用
删除文件
b. 具体实现
Win32 API DeleteFile

23. QFile::close

a. 函数作用
关闭文件
b. 具体实现
Win32 API CloseHandle
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。