25

I need to delete all files in a directory using Qt.

All of the files in the directory will have the extension ".txt".

I don't want to delete the directory itself.

Does anyone know how I can do this? I've looked at QDir but am having no luck.

demonplus
  • 5,613
  • 12
  • 49
  • 68
user1794021
  • 373
  • 3
  • 5
  • 9

8 Answers8

57

Bjorns Answer tweeked to not loop forever

QString path = "whatever";
QDir dir(path);
dir.setNameFilters(QStringList() << "*.*");
dir.setFilter(QDir::Files);
foreach(QString dirFile, dir.entryList())
{
    dir.remove(dirFile);
}
rreeves
  • 2,408
  • 6
  • 39
  • 53
14

Ignoring the txt extension filtering... Here's a way to delete everything in the folder, including non-empty sub directories:

In QT5, you can use removeRecursively() on dirs. Unfortunately, that removes the whole directory - rather than just emptying it. Here is basic a function to just clear a directory's contents.

void clearDir( const QString path )
{
    QDir dir( path );

    dir.setFilter( QDir::NoDotAndDotDot | QDir::Files );
    foreach( QString dirItem, dir.entryList() )
        dir.remove( dirItem );

    dir.setFilter( QDir::NoDotAndDotDot | QDir::Dirs );
    foreach( QString dirItem, dir.entryList() )
    {
        QDir subDir( dir.absoluteFilePath( dirItem ) );
        subDir.removeRecursively();
    }
}

Alternatively, you could use removeRecursively() on the directory you want to clear (which would remove it altogether). Then, recreate it with the same name after that... The effect would be the same, but with fewer lines of code. This more verbose function, however, provides more potential for detailed exception handling to be added if desired, e.g. detecting access violations on specific files / folders...

user3191791
  • 141
  • 1
  • 3
5

Call QDir::entryList(QDir::Files) to get a list of all the files in the directory, and then for each fileName that ends in ".txt" call QDir::remove(fileName) to delete the file.

Jeremy Friesner
  • 70,199
  • 15
  • 131
  • 234
1

You started in a good way, look at entryList and of course pass the namefilter you want.

Zlatomir
  • 6,964
  • 3
  • 26
  • 32
1

To improve on @user3191791's answer (which removes all files and directories), this answer:

  • Modernises the code with a range-based for loop
  • Provides optional error checking

The code:

struct FileOperationResult
{
    bool success;
    QString errorMessage;
};

FileOperationResult removeDirContents(const QString &dirPath)
{
    QDir dir(dirPath);

    dir.setFilter(QDir::NoDotAndDotDot | QDir::Files);
    const QStringList files = dir.entryList();
    for (const QString &fileName : files) {
        if (!dir.remove(fileName)) {
            const QString failureMessage = QString::fromUtf8(
                "Failed to remove file %1 from %2").arg(fileName, dirPath);
            return { false, failureMessage };
        }
    }

    dir.setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
    const QStringList dirs = dir.entryList();
    for (const QString &dirName : dirs) {
        QDir subDir(dir.absoluteFilePath(dirName));
        if (!subDir.removeRecursively()) {
            const QString failureMessage = QString::fromUtf8(
                "Failed to recursively remove directory %1 from %2").arg(dirName, dirPath);
            return { false, failureMessage };
        }
    }

    return { true, QString() };
}

Usage:

const FileOperationResult removeResult = removeDirContents(path);
if (!removeResult.success)
    qWarning() << removeResult.errorMessage;
Mitch
  • 23,716
  • 9
  • 83
  • 122
0

This is how I would do it:

QString path = "name-of-directory";
QDir dir(path);
dir.setNameFilters(QStringList() << "*.txt");
dir.setFilters(QDir::Files);
while(dir.entryList().size() > 0){
    dir.remove(dir.entryList().first());
}
Bjorn
  • 47
  • 4
  • 1
    I tried with your code, but it deletes one file only, and then it keeps running in the loop until it crashes... – Pietro Jul 04 '13 at 16:27
  • 1
    You are right. I get the same result. Shame on me for not testing it before posting. Luckilly rreeves posted a fix below. – Bjorn Aug 29 '13 at 07:52
0

Other variant of rreeves's code:

QDir dir("/path/to/file");

dir.setNameFilters(QStringList() << "*.*");
dir.setFilter(QDir::Files);

for(const QString &dirFile: dir.entryList()) {
  dir.remove(dirFile);
}
SergeyYu
  • 354
  • 1
  • 5
  • 20
-2

You can achieve this without using Qt: to do so, opendir, readdir, unlink, and even rmdir will be your friends. It's easy to use, just browse the man pages ;).

SeedmanJ
  • 444
  • 2
  • 8