Работа с zip архивами в Qt
Материал из Wiki.crossplatform.ru
В Qt есть не документированные классы для работы с zip архивами. Эти классы позволяют распаковывать уже существующие архивы по заданному пути, так и создавать новые архивы. Для создания используется класс QZipWriter, для распаковки QZipReader. Реализация этих классов находятся по следующему пути qt/src/gui/text в файлах qzipreader_p.h, qzipwriter_p.h и qzip.cpp. Для использования этих классов предлагаю скопировать указанные файлы в свой проект и добавить их в компиляцию.
![]() | Это приватные классы Qt, использовать на свой страх и риск. |
![]() | Оба класса содержат встроенную в исходники документацию, которую можно прочитать для получения более подробной информации. |
![]() | Если в качестве системы сборки Вы используете cmake, не забудьте добавить в файл проекта include_directories(${QT_INCLUDES}) |
[править] Использование 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("file.txt"); QString file_path = QLatin1String("/path/to/file/file.txt"); 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("directory"); QString file_name = QLatin1String("file.txt"); QString file_path = QLatin1String("/path/to/file/file.txt"); 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("/path/to/dir/"); // в данном случае завершающий '/' очень важен 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::permissions(file_path)); 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; }