遍历目录
QDir 类提供了一种与平台无关的遍历目录并获得有关文件信息的方法。为了看看 QDir 是如何使用的,我们将编写一个小的控制台应用程序,它会计算一个特定、目录以及这个目录下任意深度的子目录中所有图片所占用的空间。
应用程序的核心是由imageSpace() 函数,它递归计算出给定目录中所有图片累加的大小总和:
qlonglong imageSpace(const QString &path)
{
QDir dir(path);
qlonglong size = 0;
QStringList filters;
foreach (QByteArray format, QImageReader::supportedImageFormats())
filters += "*." + format;
foreach (QString file, dir.entryList(filters, QDir::Files))
size += QFileInfo(dir, file).size();
foreach (QString subDir, dir.entryList(QDir::Dirs
| QDir::NoDotAndDotDot))
size += imageSpace(path + QDir::separator() + subDir);
return size;
}
我们从使用给定的路径创建一个 Dir对象开始,这个给定路径可能与当前目录或者绝对地址有关系。我们传递给entryList() 函数两个参数。第一个参数是文件名过滤器的一个列表,它们可以包含"*"
和"?"
这类的通配符。在这个实例中,将只选出含有 QImage 可以读取的文件格式。第二个参数指定所要的条目类型(普通文件、目录、驱动器等)。
我们遍历这个文件列表,把它们的大小累加起来。 QFileInfo类可以访问文件的属性,如文件的大小、权限、属主和时间戳,等等。
第二个 entryList() 调用获得这个目录下所有子目录。我们遍历它们(不包括.和… )并且递归调用由唔imageSpace()以累计图片文件的大小。
为创建每一个子目录的路径,我们把当前目录的路径和子目录名称组合起来,然后用斜线把它们分隔开。除了在 Wíndows 操作系统上认可"\"
之外,QDir 在所有平台上都把"\"
认作是目录分隔符。在把路径呈现给用户的时候,可以调用QDir::convertSeparators(),这个静态函数把斜线转换为针对具体平台的正确的分隔符。
下面把 main()函数添加到小程序中:
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
QStringList args = QCoreApplication::arguments();
QString path = QDir::currentPath();
if (args.count() > 1)
path = args[1];
std::cout << "Space used by images in " << qPrintable(path)
<< " and its subdirectories is "
<< (imageSpace(path) / 1024) << " KB" << std::endl;
return 0;
}
我们使用QDir::currentPath()将路径初始化为当前目录。作为备用选择,也可以使用QDir::homePath()将它初始化为用户的主目录。如果用户在命令行中指定了一个路径,就使用它来替代前面的目录。最后,调用imageSpace()函数来计算所有图片总共占用了多少空间。
QDir类提供了其他一些与文件和目录相关的函数,如entryInfoList()(它将返回QFileInfo对象的列表)、rename()、exists()、mkdir()、rmdir()。QFile类提供了一些方便的静态函数,包括remove()和exists()。同时,QFileSystem Watcher可以通过发送directoryChanged()和fileChanged()信号,在目录或者文件发送任何改变时通知我们。
imagespace.cpp
#include <QtGui>
#include <iostream>
qlonglong imageSpace(const QString &path)
{
QDir dir(path);
qlonglong size = 0;
QStringList filters;
foreach (QByteArray format, QImageReader::supportedImageFormats())
filters += "*." + format;
foreach (QString file, dir.entryList(filters, QDir::Files))
size += QFileInfo(dir, file).size();
foreach (QString subDir, dir.entryList(QDir::Dirs
| QDir::NoDotAndDotDot))
size += imageSpace(path + QDir::separator() + subDir);
return size;
}
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
QStringList args = QCoreApplication::arguments();
QString path = QDir::currentPath();
if (args.count() > 1)
path = args[1];
std::cout << "Space used by images in " << qPrintable(path)
<< " and its subdirectories is "
<< (imageSpace(path) / 1024) << " KB" << std::endl;
return 0;
}