首先指定深度分析深度,不然会陷入代码海洋之中。
本文只分析到Win32 API/Windows Com组件层次,再下层代码不做探究
本文主要了解QFile及其具体实现,使用到父类数据的地方只讨论关键点
读写文件信息
QFile>>QFileDevice>>QIODevice>>QObject
QFile本身没有添加的成员变量,所有成员变量全部继承自父类
大部分Qt类有一个类名+Private构成的类,这个类主要用于保存数据、具体实现类功能
比如QObject具有QObjectPrivate来实现具体功能,QFile具有QFilePrivate来实现文件读写
这种数据方式是为了更新时不用动导出的头文件,使程序变更Qt版本时不用做修改,直接编译通过
QFile中具有来自QObject的成员变量d_ptr,其类型为QObjectData指针,d_ptr指向QObjectPrivate,QObjectPrivate继承自QObjectData。
QFile中d_ptr指向的是QFilePrivate
QFilePrivate>>QFileDevicePrivate>>QIODevicePrivate>>QObjectPrivate
QFilePrivate单独具有的变量是QString fileName,代表打开文件路径。其他变量都来自父类
接下来介绍QFile主要功能函数:
首先介绍下函数通用调用流程
QFile中大部分函数是先调用到QFileDevice中,再创建QFSFileEngine引擎,再由QFSFileEngine实现对应功能
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返回权限标识
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语言函数
a. 函数作用
获取文件大小
b. 具体实现函数
依靠Win32 API GetFileAttributesEx来获取文件属性
a. 函数作用
拷贝文件
b. 具体实现
Win32 API CopyFile
a. 函数作用
检查文件是否存在
b. 具体实现
Win32 API GetFileAttributesEx
a. 函数作用
文件重命名
b. 具体实现
Win32 API MoveFile
a. 函数作用
创建链接文件
b. 具体实现
通过Com组件,先找到CLSID_ShellLink,再查询到IID_IPersistFile,最后调用IPersistFile::Save创建链接
为什么不用CreateSymbolicLink实现?
CreateSymbolicLink:最低客户端Windows Vista,最低服务器Windows Server 2008
IShellLink:最低客户端Windows XP,最低服务器Windows Server 2000
a. 函数作用
更改QFile代表的文件,并不会打开文件
b. 具体实现
关闭之前打开的文件并更改QFilePrivate中保存的文件名称
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替代
a. 函数作用
返回符号链接指向的路径
b. 具体实现
通过Com组件,先找到CLSID_ShellLink,再查询到IID_IPersistFile,最后调用IShellLink::GetPath获取链接指向的文件全路径
a. 函数作用
打开文件
b. 具体实现
Win32 API CreateFile
a. 函数作用
读取文件中所有数据
b. 具体实现
Win32 API ReadFile
a. 函数作用
拷贝文件
b. 具体实现
write只是将buffer放在QIODevicePrivate::writeBuffer,除非内存大于0x4000才会写入文件中
a. 函数作用
将QIODevicePrivate::writeBuffer中数据写入到文件中
b. 具体实现
Win32 API WriteFile和fflush
a. 函数作用
删除文件
b. 具体实现
Win32 API DeleteFile
a. 函数作用
关闭文件
b. 具体实现
Win32 API CloseHandle