9. Qt5文件及磁盘处理
第 9 章 Qt5 文件及磁盘处理
Qt 提供了QFile 类用于进行文件操作。QFile 类提供了读写文件的接口,可以读写文本文件、二进制文件和Qt 的资源文件。
处理文本文件和二进制文件,可以使用QTextStream 类和QDataStream 类。处理临时文件可以使用QTemporaryFile,获取文件信息可以使用QFilelnfo,处理目录可以使用QDir,监视文件和目录变化可以使用QFileSystemWatcher 。
9.1 读写文本文件
读写文本文件的方法通常有两种:一种是直接利用传统的QFile 类方法;另一种是利用更为方便的QTextStream 类方法。
9.1.1 使用QFile类读写文本
QFile 类提供了读写文件的接口。这里首先介绍如何使用QFile 类读写文本文件。
(CH901) 建立基于控制台工程,使用QFile 类读写文本文件。
源文件"main.cpp" 的具体实现代码如下:
#include <qapplication.h>
#include <QFile>
#include <qdebug.h>
int main(int argc, char* argv[]) {
QApplication a(argc, argv);
QFile file("textFile.txt");
if (file.open(QIODevice::ReadOnly)) {
char buffer[4096];
qint64 lineLen = file.readLine(buffer, sizeof(buffer));
if (lineLen != -1) {
qDebug() << buffer;
}
}
return a.exec();
}
/*
QFile file("textFile.txt"):
打开一个文件有两种方式。一种方式是在构造函数中指定文件名;另一种方式是使用setFileName()函数设置文件名。
if( file.open(QIODevice::ReadOnly) ):
打开文件使用open()函数,关闭文件使用close()函数。此处的open()函数以只读方式打开文件,只读方式参数为QIODevice::ReadOnly,只写方式参数为QIODevice::WriteOnly,读写参数为QIODevice::ReadWrite 。
qint64 lineLen = file.readLine(buffer, sizeof(buffer)):
在QFile中可以使用从QIODevice中继承的readLine()函数读取文本文件的一行。
if(lineLen!=-1){ qDebugQ<<buffer; }:
如果读取成功,则readLine()函数返回实际读取的字节数;如果读取失败,则返回"-1" 。
*/
9.1.2 使用QTextStream 类读写文本
QTextStream提供了更为方便的接口来读写文本,它可以操作QIODevice、QByteArray和QString 。使用QTextStream的流操作符,可以方便地读写单词、行和数字。为了产生文本,QtextStream还提供了填充、对齐和数字格式化的选项。
(CH902) 建立基于控制台的工程,使用QTextStream 类读写文本文件。
操作步骤与上节的实例类似,不再重复介绍。
源文件"main.cpp" 的具体实现代码如下:
#include <qapplication.h>
#include <QFile>
#include <qdebug.h>
int main(int argc, char* argv[]) {
QApplication a(argc, argv);
QFile file("textFile.txt");
if (file.open(QFile::WriteOnly | QFile::Truncate)) {
QTextStream out(&file);
out << QObject::tr("score:") << qSetFieldWidth(10) <<
left << 90 << endl;
}
return a.exec();
}
/*
if (file.open(QFile::WriteOnly | QFile::Truncate)):
参数QFile::Truncate表示将原来文件中的内容清空。输出时将格式设为左对齐,占10 个字符位置。
out << QObject::tr("score:") << qSetFieldWidth(10) << left << 90 << endl:
用户使用格式化函数和流操作符设置需要的输出格式。其中,qSetFieldWidth()函数是设置字段宽度的格式化函数。除此之外,QTextStream还提供了其他一些格式化函数,见表9.1。
其中,left操作符是QTextStream定义的类似于<iostream>中的流操作符。QTextStream还提供了其他一些流操作符,见表9.2 。
*/
函数 | 功能描述 |
---|---|
qSetFieldWidth(int width) | 设置字段宽度 |
qSetPadChar(QChar ch) | 设置填充字符 |
qSetRea!NumberPercision(int precision) | 设置实数精度 |
操作符 | 作用描述 |
---|---|
bin | 设置读写的整数为二进制数 |
oct | 设置读写的整数为八进制数 |
dec | 设置读写的整数为十进制数 |
hex | 设置读写的整数为十六进制数 |
showbase | 强制显示进制前缀,如十六进制(0x) 、八进制(o) 、二进制(0b) |
forcesign | 强制显示符号(+, -) |
forcepoint | 强制显示小数点 |
noshowbase | 不显示进制前缀 |
noforcesign | 不显示符号 |
uppercasebase | 显示大写的进制前缀 |
lowercasebase | 显示小写的进制前缀 |
uppercasedigits | 用大写字母表示 |
lowercasedigits | 用小写字母表示 |
fixed | 用固定小数点表示 |
scientific | 用科学计数法表示 |
left | 左对齐 |
right | 右对齐 |
center | 居中 |
endl | 换行 |
flush | 清除缓冲 |
在QTextStream中使用的默认编码是QTextCodec: :codecForLocale()函数返回的编码,同时能够自动检测Unicode,也可以使用QTextStream::setCodec(QTextCodec *codec) 函数设置流的编码。
9.2 读写二进制文件
QDataStrearn类提供了将二进制文件串行化的功能,用于实现C++基本数据类型,如char 、short 、int、char*等的串行化。更复杂的串行化操作则是通过将数据类型分解为基本类型来完成的。
(CH903)使用QDataStrearn 读写二进制文件。
头文件"mainwindow.h"的具体代码如下:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
void fileFun();
};
#endif // MAINWINDOW_H
源文件"mainwindow . cpp" 的具体代码如下:
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent){
fileFun();
}
// 函数fileFun()完成主要功能,其具体代码如下:
void MainWindow::fileFun() {
/*将二进制数据写到数据流 */ //
QFile file("binary.dat");
file.open(QIODevice::WriteOnly | QIODevice::Truncate);
QDataStream out(&file); // 将数据序列化
out << QString(tr("周何骏:")); // 字符串序列化
out << QDate::fromString("1996/09/25", "yyyy/MM/dd");
out << (qint32)23; // 整数序列化
file.close();
/*从文件中读取数据 */ //
file.setFileName("binary.dat");
if(!file.open(QIODevice::ReadOnly)) {
qDebug() << "error!";
return;
}
QDataStream in(&file); // 从文件中读出数据
QString name;
QDate birthday;
qint32 age;
in >> name >> birthday >> age; // 获取字符串和整数
qDebug() << name << birthday << age;
file.close();
}
/*
从QFile file("binary.dat")到file.close()之间的代码段:
每一个条目都以定义的二进制格式写入文件。Qt中的很多类型,包括QBrush、QColor、QDateTime、QFont、QPixmap、QString、QVariant等都可以写入数据流。QDataStream类写入了name(QString)、birthday(QDate)和age(qint32)这三个数据。注意,在读取时也要使用相同的类型读出。
从file.setFileName("binary.dat")到file.close()之间的代码段:
QDataStream类可以读取任意的以QIODevice为基类的类生成对象产生的数据,如QTcpSocket、QUdpSocket、QBuffer、QFile、QProcess等类的数据。可以使用QDataStream在QAbstractSocket一端写数据,在另一端使用QDataStream读取数据,这样就免去了烦琐的高低字节转换工作。如果需要读取原始数据,则可以使用readRawdata()函数读取数据并保存到预先定义好的char*缓冲区,写原始数据使用writeRawData()函数。读写原始数据需要对数据进行编码和解码。
*/
9.3 目录操作与文件系统
QDir类具有存取目录结构和内容的能力,使用它可以操作目录、存取目录或文件信息、操作底层文件系统,而且还可以存取Qt 的资源文件。
Qt使用"/" 作为通用的目录分隔符和URL 路径分隔符。如果在程序中使用"/" 作为目录分隔符, Qt会将其自动转换为符合底层操作系统的分隔符(如Linux使用"/",Windows 使用"\")。
QDir可以使用相对路径或绝对路径指向一个文件。isRelative()和isAbsolute()函数可以判断QDir对象使用的是相对路径还是绝对路径。如果需要将一个相对路径转换为绝对路径,则使用makeAbsolute()函数。
目录的路径可以通过path()函数返回,通过setPath()函数设置新路径。绝对路径使用absolutePath()函数返回,目录名可以使用dirName()函数获得,它通常返回绝对路径中的最后一个元素,如果QDir指向当前目录,则返回"."。目录的路径可以通过cd()和cdUp()函数改变。可以使用mkdir()函数创建目录,使用rename()函数改变目录名。
判断目录是否存在可以使用exists()函数,目录的属性可以使用isReadable()、isAbsolute()、isRelative()和isRoot()函数来获取。目录下有很多条目,包括文件、目录和符号连接,总的条目数可以使用count()函数来统计。entryList()函数返回目录下所有条目组成的字符串链表。可以使用remove()函数删除文件,使用rmdir()函数删除目录。
9.3.1 文件大小及路径获取实例
(CH904) 得到一个文件的大小和所在的目录路径。
源文件"main.cpp" 的具体代码如下:
#include <qapplication.h>
#include <QFile>
#include <QStringList>
#include <QDir>
#include <QtDebug>
qint64 du(const QString& path) {
QDir dir(path);
qint64 size = 0;
foreach(QFileInfo fileInfo, dir.entryInfoList(QDir::Files)) {
size += fileInfo.size();
}
foreach(QString subDir, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {
size += du(path + QDir::separator() + subDir);
}
char unit = 'B';
qint64 curSize = size;
if (curSize > 1024) {
curSize /= 1024;
unit = 'K';
if (curSize > 1024) {
curSize /= 1024;
unit = 'M';
if (curSize > 1024) {
curSize /= 1024;
unit = 'G';
}
}
}
qDebug() << curSize << unit << "\t" << qPrintable(path) << endl;
return size;
}
int main(int argc, char* argv[]) {
QApplication a(argc, argv);
QStringList args = a.arguments();
QString path;
if (args.count() > 1) {
path = args[1];
}
else {
path = QDir::currentPath();
}
qDebug() << path << endl;
du(path);
return a.exec();
}
9.3.2 文件系统浏览
文件系统的浏览是目录操作的一个常用功能。本节介绍如何使用QDir 类显示文件系统目录及用过滤方式显示文件列表的方法。
(CH905) 文件系统的浏览。
在头文件"fileview.h" 中,类FileView继承自QDialog类,具体代码如下:
#ifndef FILEVIEW_H
#define FILEVIEW_H
#include <QDialog>
#include <QLineEdit>
#include <QListWidget>
#include <QVBoxLayout>
#include <QDir>
#include <QListWidgetItem>
#include <QFileInfoList>
class FileView : public QDialog {
Q_OBJECT
public:
FileView(QWidget *parent=0,Qt::WindowFlags f=0);
~FileView();
void showFileInfoList(QFileInfoList list);
public slots:
void slotShow(QDir dir);
void slotDirShow(QListWidgetItem * item);
private:
QLineEdit *fileLineEdit;
QListWidget *fileListWidget;
QVBoxLayout *mainLayout;
};
#endif // FILEVIEW_H
源文件"fileview.cpp" 的具体代码如下:
#include "fileview.h"
#include <QStringList>
#include <QIcon>
FileView::FileView(QWidget *parent,Qt::WindowFlags f)
: QDialog(parent,f)
{
setWindowTitle(tr("File View"));
fileLineEdit = new QLineEdit(tr("/"));
fileListWidget = new QListWidget;
mainLayout = new QVBoxLayout(this);
mainLayout->addWidget(fileLineEdit);
mainLayout->addWidget(fileListWidget);
connect(fileLineEdit,SIGNAL(returnPressed()),this,SLOT (slotShow (QDir)));
connect(fileListWidget,SIGNAL(itemDoubleClicked (QListWidgetItem*)),
this,SLOT(slotDirShow(QListWidgetItem*)));
QString root = "/";
QDir rootDir(root);
QStringList string;
string << "*";
QFileInfoList list=rootDir.entryInfoList(string);
showFileInfoList(list);
}
// 槽函数slotShow()实现了显示目录dir下的所有文件,具体内容如下:
void FileView::slotShow(QDir dir) {
QStringList string;
string<<"*";
QFileInfoList list=dir.entryInfoList(string,QDir::AllEntries,
QDir:: DirsFirst); //
showFileInfoList(list);
}
/*
QFilelnfoList list=dir.entrylnfoList(string,
QDir::AllEntries, QDir::DirsFirst):
QDir的entrylnfoList()方法是按照某种过滤方式获得目录下的文件列表。其函数原型如下:
QFileInfoList entryInfoList(
const QStringList &nameFilters, // 此参数指定了文件名的过滤方式,如"*" ".tar.gz"
Filters filters = NoFilter,// 此参数指定了文件属性的过滤方式,如目录、文件、读写属性等
SortFlags sort = NoSort // 此参数指定了列表的排序情况
) const;
其中,QDir::Filter定义了一系列的过滤方式,见表9.3。QDir::SortFlag定义了一系列排序方式,见表9.4 。
*/
// 函数showFilelnfoList()实现了用户可以双击浏览器中显示的目录进入下一级目录,或单击" .. "返回上一级目录,顶部的编辑框显示当前所在的目录路径,列表中显示该目录下的所有文件。其具体代码如下:
void FileView::showFileInfoList(QFileInfoList list) {
fileListWidget->clear(); // 首先清空列表控件
for(unsigned int i=0; i<list.count(); i++) { //
QFileInfo tmpFileInfo=list.at(i);
if(tmpFileInfo.isDir()) {
QIcon icon("dir.png");
QString fileName = tmpFileInfo.fileName();
QListWidgetItem *tmp = new QListWidgetItem(icon,fileName);
fileListWidget->addItem(tmp);
} else if(tmpFileInfo.isFile()) {
QIcon icon("file.png");
QString fileName=tmpFileInfo.fileName();
QListWidgetItem *tmp = new QListWidgetItem(icon,fileName);
fileListWidget->addItem(tmp);
}
}
}
/*
for(unsigned int i=0; i<list.count(); i++){ …}:
依次从QFilelnfoList 对象中取出所有项,按目录和文件两种方式加入列表控件中。
*/
// 槽函数slotDirShow()根据用户的选择显示下一级目录的所有文件。其具体实现代码如下:
void FileView::slotDirShow(QListWidgetItem * item) {
QString str=item->text(); //将下一级的目录名保存在str中
QDir dir; //定义一个QDir对象
dir.setPath(fileLineEdit->text()); //设置QDir对象的路径为当前目录路径
dir.cd(str); //根据下一级目录名重新设置QDir对象的路径
fileLineEdit->setText(dir.absolutePath()); //
slotShow(dir); //显示当前目录下的所有文件
}
/*
fileLineEdit->setText(dir.absolutePath()):
刷新显示当前的目录路径。Qdir的absolutePath()方法用于获取目录的绝对路径,即以"/"开头的路径名,同时忽略多余的"."或".."及多余的分隔符。
过滤方式 | 作用描述 |
---|---|
QDir::Dirs | 按照过滤方式列出所有目录 |
QDir::AllDirs | 列出所有目录,不考虑过滤方式 |
QDir::Files | 只列出文件 |
QDir::Drives | 列出磁盘驱动器(UNIX 系统无效) |
QDir: :NoSymLinks | 不列出符号连接(对不支持符号连接的操作系统无效) |
QDir: :NoDotAndDotDot | 不列出“.”和“ … ” |
QDir: :AllEntries | 列出目录、文件和磁盘驱动器,相当于DirslFileslDrives |
QDir: :Readable | 列出所有具有“读”属性的文件和目录 |
QDir:: Writable | 列出所有具有“写”属性的文件和目录 |
QDir: :Executable | 列出所有具有“执行”属性的文件和目录 |
QDir: :Modified | 只列出被修改过的文件(UNIX系统无效) |
QDir::Hidden | 列出隐藏文件(在UNIX系统下,隐藏文件的文件名以“.”开始) |
QDir::System | 列出系统文件(在UNIX系统下指FIFO 、套接字和设备文件) |
QDir::CaseSensitive | 文件系统如果区分文件名大小写,则按大小写方式进行过滤 |
排序方式 | 作用描述 |
---|---|
QDir::Name | 按名称排序 |
QDir::Time | 按时间排序(修改时间) |
QDir::Size | 按文件大小排序 |
QDir::Type | 按文件类型排序 |
QDir:: Unsorted | 不排序 |
QDir: :DirsFirst | 目录优先排序 |
QDir::DirsLast | 目录最后排序 |
QDir: :Reversed | 反序 |
QDir: :lgnoreCase | 忽略大小写方式排序 |
QDir::LocaleAware | 使用当前本地排序方式进行排序 |
9.4 获取文件信息
QFilelnfo类提供了对文件进行操作时获得的文件相关属性信息,包括文件名、文件大小、创建时间、最后修改时间、最后访问时间及一些文件是否为目录、文件或符号链接和读写属性等。
在头文件"fileinfo.h" 中,类Filelnfo 继承自QDialog 类,此类中声明了用到的各种相关控件和函数,其具体内容如下:
#ifndef FILEINFO_H
#define FILEINFO_H
#include <QDialog>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QCheckBox>
class FileInfo : public QDialog
{
Q_OBJECT
public:
FileInfo(QWidget *parent = 0,Qt::WindowFlags f=0);
~FileInfo();
public slots:
void slotFile();
void slotGet();
private:
QLabel *fileNameLabel;
QLineEdit *fileNameLineEdit;
QPushButton *fileBtn;
QLabel *sizeLabel;
QLineEdit *sizeLineEdit;
QLabel *createTimeLabel;
QLineEdit *createTimeLineEdit;
QLabel *lastModifiedLabel;
QLineEdit *lastModifiedLineEdit;
QLabel *lastReadLabel;
QLineEdit *lastReadLineEdit;
QLabel *propertyLabel;
QCheckBox *isDirCheckBox;
QCheckBox *isFileCheckBox;
QCheckBox *isSymLinkCheckBox;
QCheckBox *isHiddenCheckBox;
QCheckBox *isReadableCheckBox;
QCheckBox *isWritableCheckBox;
QCheckBox *isExecutableCheckBox;
QPushButton *getBtn;
};
#endif // FILEINFO_H
源文件"fileinfo.cpp" 的具体内容如下:
#include "fileinfo.h"
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QFileDialog>
#include <QDateTime>
FileInfo::FileInfo(QWidget *parent,Qt::WindowFlags f)
: QDialog(parent,f) {
fileNameLabel = new QLabel(tr("文件名:"));
fileNameLineEdit = new QLineEdit;
fileBtn = new QPushButton(tr("文件"));
sizeLabel = new QLabel(tr("大小:"));
sizeLineEdit = new QLineEdit;
createTimeLabel = new QLabel(tr("创建时间:"));
createTimeLineEdit = new QLineEdit;
lastModifiedLabel = new QLabel(tr("最后修改时间:"));
lastModifiedLineEdit = new QLineEdit;
lastReadLabel = new QLabel(tr("最后访问时间:"));
lastReadLineEdit = new QLineEdit;
propertyLabel = new QLabel(tr("属性:"));
isDirCheckBox = new QCheckBox(tr("目录"));
isFileCheckBox = new QCheckBox(tr("文件"));
isSymLinkCheckBox = new QCheckBox(tr("符号连接"));
isHiddenCheckBox = new QCheckBox(tr("隐藏"));
isReadableCheckBox = new QCheckBox(tr("读"));
isWritableCheckBox = new QCheckBox(tr("写"));
isExecutableCheckBox = new QCheckBox(tr("执行"));
getBtn = new QPushButton(tr("获得文件信息"));
QGridLayout *gridLayout = new QGridLayout;
gridLayout->addWidget(fileNameLabel,0,0);
gridLayout->addWidget(fileNameLineEdit,0,1);
gridLayout->addWidget(fileBtn,0,2);
gridLayout->addWidget(sizeLabel,1,0);
gridLayout->addWidget(sizeLineEdit,1,1,1,2);
gridLayout->addWidget(createTimeLabel,2,0);
gridLayout->addWidget(createTimeLineEdit,2,1,1,2);
gridLayout->addWidget(lastModifiedLabel,3,0);
gridLayout->addWidget(lastModifiedLineEdit,3,1,1,2);
gridLayout->addWidget(lastReadLabel,4,0);
gridLayout->addWidget(lastReadLineEdit,4,1,1,2);
QHBoxLayout *layout2 = new QHBoxLayout;
layout2->addWidget(propertyLabel);
layout2->addStretch();
QHBoxLayout *layout3 = new QHBoxLayout;
layout3->addWidget(isDirCheckBox);
layout3->addWidget(isFileCheckBox);
layout3->addWidget(isSymLinkCheckBox);
layout3->addWidget(isHiddenCheckBox);
layout3->addWidget(isReadableCheckBox);
layout3->addWidget(isWritableCheckBox);
layout3->addWidget(isExecutableCheckBox);
QHBoxLayout *layout4 = new QHBoxLayout;
layout4->addWidget(getBtn);
QVBoxLayout *mainLayout = new QVBoxLayout(this);
mainLayout->addLayout(gridLayout);
mainLayout->addLayout(layout2);
mainLayout->addLayout(layout3);
mainLayout->addLayout(layout4);
connect(fileBtn,SIGNAL(clicked()),this,SLOT(slotFile()));
connect(getBtn,SIGNAL(clicked()),this,SLOT(slotGet()));
}
// 槽函数slotFile()完成通过标准文件对话框获得所需要文件的文件名功能,其具体内容如下:
void FileInfo::slotFile() {
QString fileName = QFileDialog::getOpenFileName(this,"打开","/", "files (*)");
fileNameLineEdit->setText(fileName);
}
// 槽函数slotGet() 通过QFilelnfo 获得具体的文件信息,其具体内容如下:
void FileInfo::slotGet() {
QString file = fileNameLineEdit->text();
QFileInfo info(file); // 根据输入参数创建一个QFileInfo对象
qint64 size = info.size(); // 获得QFileInfo对象的大小
QDateTime created = info.created(); // 获得QFileInfo对象的创建时间
QDateTime lastModified = info.lastModified(); // 获得QFileInfo对象的最后修改时间
QDateTime lastRead = info.lastRead(); // 获得QFileInfo对象的最后访问时间
/* 判断QFileInfo对象的文件类型属性 */
bool isDir = info.isDir(); // 是否为目录
bool isFile = info.isFile(); // 是否为文件
bool isSymLink = info.isSymLink(); //
bool isHidden = info.isHidden(); // 判断QFileInfo对象的隐藏属性
bool isReadable = info.isReadable(); // 判断QFileInfo对象的读属性
bool isWritable = info.isWritable(); // 判断QFileInfo对象的写属性
bool isExecutable = info.isExecutable();
//判断QFileInfo对象的可执行属性
/* 根据上面得到的结果更新界面显示 */
sizeLineEdit->setText(QString::number(size));
createTimeLineEdit->setText(created.toString());
lastModifiedLineEdit->setText(lastModified.toString());
lastReadLineEdit->setText(lastRead.toString());
isDirCheckBox->setCheckState(isDir?Qt::Checked: Qt::Unchecked);
isFileCheckBox->setCheckState(isFile?Qt::Checked: Qt::Unchecked);
isSymLinkCheckBox->setCheckState(isSymLink?Qt::Checked: Qt::Unchecked);
isHiddenCheckBox->setCheckState(isHidden?Qt::Checked: Qt:: Unchecked);
isReadableCheckBox->setCheckState(isReadable?Qt::Checked: Qt::Unchecked);
isWritableCheckBox->setCheckState(isWritable?Qt::Checked: Qt::Unchecked);
isExecutableCheckBox->setCheckState(isExecutable?Qt::Checked: Qt::Unchecked);
}
/*
bool isSymLink = info.isSymLink():
判断QFilelnfo对象的文件类型属性,此处判断是否为符号连接。而symLinkTarget()方法可进一步获得符号连接指向的文件名称。
*/
FileInfo::~FileInfo() {
}
文件的所有权限可以由owner()、ownerId()、group()、groupld()等方法获得。测试一个文件的权限可以使用Permission()方法。
为了提高执行的效率,QFilelnfo可以将文件信息进行一次读取缓存,这样后续的访问就不需要持续访问文件了。但是,由于文件在读取信息之后可能被其他程序或本程序改变属性,所以QFilelnfo通过refresh()方法提供了一种可以更新文件信息的刷新机制,用户也可以通过setCaching()方法关闭这种缓冲功能。
QFilelnfo可以使用绝对路径和相对路径指向同一个文件。其中,绝对路径以"/"开头(在Windows 中以磁盘符号开头),相对路径则以目录名或文件名开头,isRelative()方法可以用来判断QFilelnfo使用的是绝对路径还是相对路径。makeAbsolute()方法可以用来将相对路径转化为绝对路径。
9.5 监视文件和目录变化
在Qt中可以使用QFileSystemWatcher类监视文件和目录的改变。在使用addPath()函数监视指定的文件和目录时,如果需要监视多个目录,则可以使用addPaths()函数加入监视。若要移除不需要监视的目录,则可以使用removePath()和removePaths()函数。
当监视的文件被修改或删除时,产生一个fileChanged()信号。如果所监视的目录被改变或删除,则产生directoryChanged()信号。
(CH907)监视指定目录功能,介绍如何使用QFileSystemWatcher。
在头文件"watcher.h"中,Watcher类继承自QWidget类,其具体内容如下:
#ifndef WATCHER_H
#define WATCHER_H
#include <QWidget>
#include <QLabel>
#include <QFileSystemWatcher>
class Watcher : public QWidget {
Q_OBJECT
public:
Watcher(QWidget *parent = 0);
~Watcher();
public slots:
void directoryChanged(QString path);
private:
QLabel *pathLabel;
QFileSystemWatcher fsWatcher;
};
#endif // WATCHER_H
源文件"watcher.cpp" 的具体内容如下:
#include "watcher.h"
#include <QVBoxLayout>
#include <QDir>
#include <QMessageBox>
#include <QApplication>
Watcher::Watcher(QWidget *parent)
: QWidget(parent) {
QStringList args=qApp->arguments();
QString path;
if(args.count()>1) {
path=args[1];
} else {
path=QDir::currentPath();
}
pathLabel = new QLabel;
pathLabel->setText(tr("监视的目录:")+path);
QVBoxLayout *mainLayout = new QVBoxLayout(this);
mainLayout->addWidget(pathLabel);
fsWatcher.addPath(path);
connect(&fsWatcher,SIGNAL(directoryChanged(QString)),
this,SLOT(directoryChanged(QString)));
}
/*
if(args.count()>1){…}:
读取命令行指定的目录作为监视目录。如果没有指定,则监视当前目录。
connect(&fsWatcher, SIGNAL(directoryChanged(QString)),
this, SLOT(directoryChanged(QString))):
将目录的directoryChanged()信号与响应函数directoryChanged()连接。
*/
// 响应函数directoryChangedO使用消息对话框提示用户目录发生了改变,具体实现代码如下:
void Watcher::directoryChanged(QString path) {
QMessageBox::information(NULL,tr("目录发生变化"), path);
}
Watcher::~Watcher() {
}
来源:《Qt开发及实例(第四版)》
推荐阅读