欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

9. Qt5文件及磁盘处理

程序员文章站 2024-03-22 21:13:10
...

第 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 。
*/
表9.1 QTextStream 的格式化函数
函数 功能描述
qSetFieldWidth(int width) 设置字段宽度
qSetPadChar(QChar ch) 设置填充字符
qSetRea!NumberPercision(int precision) 设置实数精度
表9.2 QTextStream 的流操作符
操作符 作用描述
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()方法用于获取目录的绝对路径,即以"/"开头的路径名,同时忽略多余的"."或".."及多余的分隔符。
表9.3 QDir::Filter定义的过滤方式
过滤方式 作用描述
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 文件系统如果区分文件名大小写,则按大小写方式进行过滤
表9.4 QDir::SortFlag定义的排序方式
排序方式 作用描述
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开发及实例(第四版)》