Home > Articles > Programming > C/C++

  • Print
  • + Share This
This chapter is from the book

Traversing Directories

The QDir class provides a platform-independent means of traversing directories and retrieving information about files. To see how QDir is used, we will write a small console application that calculates the space consumed by all the images in a particular directory and all its subdirectories to any depth.

The heart of the application is the imageSpace() function, which recursively computes the cumulative size of a given directory's images:

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;
}

We begin by creating a QDir object using the given path, which may be relative to the current directory or absolute. We pass the entryList() function two arguments. The first is a list of file name filters. These can contain '*' and '?' wildcard characters. In this example, we are filtering to include only file formats that QImage can read. The second argument specifies what kinds of entries we want (normal files, directories, drives, etc.).

We iterate over the list of files, accumulating their sizes. The QFileInfo class allows us to access a file's attributes, such as the file's size, permissions, owner, and timestamps.

The second entryList() call retrieves all the subdirectories in this directory. We iterate over them (excluding . and ..) and recursively call imageSpace() to ascertain their accumulated image sizes.

To create each subdirectory's path, we combine the current directory's path with the subdirectory name, separating them with a slash. QDir treats '/' as a directory separator on all platforms, in addition to recognizing '\' on Windows. When presenting paths to the user, we can call the static function QDir::toNativeSeparators() to convert slashes to the correct platform-specific separator.

Let's add a main() function to our small program:

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;
}

We use QDir::currentPath() to initialize the path to the current directory. Alternatively, we could have used QDir::homePath() to initialize it to the user's home directory. If the user has specified a path on the command line, we use that instead. Finally, we call our imageSpace() function to calculate how much space is consumed by images.

The QDir class provides other file- and directory-related functions, including entryInfoList() (which returns a list of QFileInfo objects), rename(), exists(), mkdir(), and rmdir(). The QFile class provides some static convenience functions, including remove() and exists(). And the QFileSystemWatcher class can notify us when a change occurs to a directory or to a file, by emitting directoryChanged() and fileChanged() signals.

  • + Share This
  • 🔖 Save To Your Account