Работа с zip архивами в Qt

Материал из Wiki.crossplatform.ru

Перейти к: навигация, поиск

В Qt есть не документированные классы для работы с zip архивами. Эти классы позволяют распаковывать уже существующие архивы по заданному пути, так и создавать новые архивы. Для создания используется класс QZipWriter, для распаковки QZipReader. Реализация этих классов находятся по следующему пути qt/src/gui/text в файлах qzipreader_p.h, qzipwriter_p.h и qzip.cpp.

Замечание Замечание: Это приватные классы Qt, использовать на свой страх и риск.

Для использования этих классов предлагаю скопировать указанные файлы в свой проект и добавить их в компиляцию.

Замечание Замечание: Оба класса содержат встроенную в исходники документацию, которую можно прочитать для получения более подробной информации.


Использование QZipWriter (создание архивов)

QZipWriter - класс который может быть использован для создания ZIP-архива содержащего любое количество файлов и каталогов.

Важным моментом при создании архива является сохранение атрибутов (permissions) файлов и директорий. Они должны быть выставлены для класса QZipWriter перед добавлением каждого файла или директории.

#include <QtCore>
 
#include "qzipreader_p.h"
#include "qzipwriter_p.h"
 
int main ()
{
 
    {// Архивация файла
        QZipWriter zip(QLatin1String("file.zip"));
        if (zip.status() != QZipWriter::NoError)
            return -1;
 
        zip.setCompressionPolicy(QZipWriter::AutoCompress);
 
        QString file_name = QLatin1String("host_graph.xml.ini");
        QString file_path = QLatin1String("/home/igor_bogomolov/.config/k095-client/host_graph.xml.ini");
        QFile file(file_path);
        if (!file.open(QIODevice::ReadOnly))
            return -1;
 
        zip.setCreationPermissions(QFile::permissions(file_path));
        zip.addFile(file_name, file.readAll());
        zip.close();
    }
 
//-----------------------------------------------------------------------
    {// Архивация файла внутри директории
        QZipWriter zip(QLatin1String("file_in_dir.zip"));
        if (zip.status() != QZipWriter::NoError)
            return -1;
 
        zip.setCompressionPolicy(QZipWriter::AutoCompress);
 
        QString dir_name  = QLatin1String("k095_client");
        QString file_name = QLatin1String("host_graph.xml.ini");
        QString file_path = QLatin1String("/home/igor_bogomolov/.config/k095-client/host_graph.xml.ini");
        QFile file(file_path);
        if (!file.open(QIODevice::ReadOnly))
            return -1;
 
        //обязательно выставить атрибуты для директории
        zip.setCreationPermissions(QFile::ReadOwner|QFile::WriteOwner|QFile::ExeOwner |
                                   QFile::ReadGroup|QFile::ExeGroup |
                                   QFile::ExeOther);
        zip.addDirectory(dir_name);
 
        zip.setCreationPermissions(QFile::permissions(file_path));
        zip.addFile(dir_name + QDir::separator() + file_name, file.readAll());
        zip.close();
    }
 
//-----------------------------------------------------------------------
    {// Рекурсивная архивация директории
        QZipWriter zip(QLatin1String("dir.zip"));
        if (zip.status() != QZipWriter::NoError)
            return -1;
 
        zip.setCompressionPolicy(QZipWriter::AutoCompress);
 
        QString path = QLatin1String("/home/igor_bogomolov/.config/k095-client/");
        QDirIterator it(path, QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot,
                        QDirIterator::Subdirectories);
        while (it.hasNext()) {
            QString file_path = it.next();
            if (it.fileInfo().isDir()) {
                zip.setCreationPermissions(QFile::ReadOwner|QFile::WriteOwner|QFile::ExeOwner |
                                           QFile::ReadGroup|QFile::ExeGroup |
                                           QFile::ExeOther);
                zip.addDirectory(file_path.remove(path));
            } else if (it.fileInfo().isFile()) {
                QFile file(file_path);
                if (!file.open(QIODevice::ReadOnly))
                    continue;
 
                zip.setCreationPermissions(QFile::permissions(file_path));
                QByteArray ba = file.readAll();
                zip.addFile(file_path.remove(path), ba);
            }
        }
        zip.close();
    }
 
    return 0;
}


Использование QZipReader (извлечение данных из архивов)

QZipReader - класс который может быть использован для извлечения данных из ZIP-архива. Для этого необходимо использовать метод extractAll. Так же данный класс может быть использован для просмотра структуры архива, при помощи методов fileInfoList и entryInfoAt, а так же для извлечения отдельных данных, при помощи метода fileData.

#include <QtCore>
 
#include "qzipreader_p.h"
#include "qzipwriter_p.h"
 
int main ()
{
    QZipReader zip_reader(QLatin1String("file.zip"));
    if (zip_reader.exists()) {
        // вывод информации об архиве
        qDebug() << "Number of items in the zip archive =" << zip_reader.count();
        foreach (QZipReader::FileInfo info, zip_reader.fileInfoList()) {
            if(info.isFile)
                qDebug() << "File:" << info.filePath << info.size;
            else if (info.isDir)
                qDebug() << "Dir:" << info.filePath;
            else
                qDebug() << "SymLink:" << info.filePath;
        }
 
        // распаковка архива по указанному пути
        zip_reader.extractAll(QLatin1String("./"));
    }
    return 0;
}


Обсуждение

Обсудить на форуме...