'Zip directory recursion

I am working on creating zip archive using old Qt - ZipWriter class. The problem is when I want to add the directory. The default Qt code for addDirectory method - d->addEntry(ZipWriterPrivate::Directory, archDirName, QByteArray());. It does not add any content, only the empty directory. So, I have improved it to add the directories and content as well.

My code:

QList<QString> dirs;
int recursion = 0;

void ZipWriter::addDirectory(const QString &dirPath)
{
    QDir archDir(dirPath);
    archDir.setFilter(QDir::AllEntries | QDir::NoDotAndDotDot);
    dirs << addDirSeparator(archDir.dirName());

    if (archDir.exists()) {
        QString archDirName = "";

        if (recursion > 0) {
            for (int i = recursion; i < dirs.count(); i++) {
                 archDirName = dirs.first().append(dirs.at(i));
            }
        } else {
            archDirName = dirs.at(recursion);
        }

        if (!archDir.isEmpty()) {
            const QStringList archFileList = archDir.entryList();

            if (archFileList.count() > 0) {
                for (QString archFile : archFileList) {
                     QFileInfo archFileInfo(QDir::toNativeSeparators(QString("%1/%2").arg(archDir.absolutePath(), archFile)));

                     if (archFileInfo.isDir()) {
                         recursion++;
                         addDirectory(archFileInfo.absoluteFilePath());
                     } else {
                         QFile zipFile(archFileInfo.absoluteFilePath());
                         zipFile.open(QIODevice::ReadOnly);
                         addFile(QString("%1%2").arg(archDirName, archFile), zipFile.readAll());
                         zipFile.close();
                     }
                }
            }
        } else {
            d->addEntry(ZipWriterPrivate::Directory, archDirName, QByteArray());
        }
    }
}

Now, it adds the directory and content recursively but it has issue when directory is on the same level, it appends it to the end. I think, I must use the STL container to keep track of the directory for example QMap but the question is how to get the current directory level? Any ideas? Thank you.

Updated: 01.05.2022

I have change my code to this:

void ZipWriter::addDirectory(const QString &dirPath)
{
    QDirIterator dirIt(dirPath, QDir::AllEntries | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
    while (dirIt.hasNext()) {
        QString archDirPath = dirIt.next();    
        QFile zipFile(archDirPath);
        zipFile.open(QIODevice::ReadOnly);

        if (!dirIt.fileInfo().isDir()) {
            addFile(archDirPath, zipFile.readAll());
        }

        zipFile.close();
    }
}

It adds everything recursively and in correct order but I have another issue. Now, it adds the full path to the archive. For example, I want to add this folder and it's content to the archive: 22610.1_amd64_en-us_professional_00fb7ba0_convert. In the archive I get: C:\Users\userProfile\Downloads\22610.1_amd64_en-us_professional_00fb7ba0_convert. Any ideas how to make this relative path or trim it? Thank you.



Solution 1:[1]

You can use QDirIterator to recursively iterate over directory and subdirectories, and I believe you dont need to add nonempty directories at all, just files will be fine.

And why would you use stl container in qt, please use qt containers.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 mugiseyebrows