У меня есть каталог с файлами и папками, которые я бы хотел сжать. Я использую квазип qt-project для этого. Поэтому я решил написать функцию, которая упаковывает все содержимое каталога, включая файловую структуру.
Как мне создать папку в zip-файле? Я попробовал это с QuaZipNewInfo, но не смог заставить его работать.
Например, я хочу сжать tmp-папку с таким содержимым:
tmp/1.txt
tmp/folder1/2.txt
tmp/folder1/3.txt
tmp/folder2/4.txt
tmp/folder2/folder3/5.txt
Что я получаю после распаковки файла с помощью обычного инструмента архивирования (Archive Utility):
tmp/1.txt
tmp/2.txt
tmp/3.txt
tmp/4.txt
tmp/5.txt
Это то, что я до сих пор:
void Exporter::zipFilelist(QFileInfoList& files, QuaZipFile& outFile, QFile& inFile, QFile& inFileTmp)
{
char c;
foreach(QFileInfo file, files) {
if(file.isDir() && file.fileName() != "." && file.fileName() != "..") {
QFileInfoList infoList = QDir(file.filePath()).entryInfoList();
zipFilelist(infoList, outFile, inFile, inFileTmp);
}
if(file.isFile()) {
inFileTmp.setFileName(file.fileName());
inFile.setFileName(file.filePath());
if(!inFile.open(QIODevice::ReadOnly)) {
qDebug() << "testCreate(): inFile.open(): " << inFile.errorString().toLocal8Bit().constData();
}
QuaZipNewInfo info(inFileTmp.fileName(), inFile.fileName());
if(!outFile.open(QIODevice::WriteOnly, info)) {
qDebug() << "testCreate(): outFile.open(): " << outFile.getZipError();
}
while(inFile.getChar(&c)&&outFile.putChar(c)) ;
if(outFile.getZipError()!=UNZ_OK) {
qDebug() << "testCreate(): outFile.putChar(): %d"<< outFile.getZipError();
}
outFile.close();
if(outFile.getZipError()!=UNZ_OK) {
qDebug() << "testCreate(): outFile.close(): %d"<< outFile.getZipError();
}
inFile.close();
}
}
}
И вот как я называю функцию:
QFileInfoList files = QDir(sourceFolder).entryInfoList();
QFile inFile;
QFile inFileTmp;
QuaZipFile outFile(&zip);
zipFilelist(files, outFile, inFile, inFileTmp);
Я не получаю никакой ошибки. Когда я хочу распаковать файл, он не извлекает папки (потому что я, вероятно, не упаковываю их в zip-архив !?). Таким образом, я получаю все файлы всех подпапок, распакованных в одну папку.
Похоже, что в вашей функции вы рекурсивно получали файлы в папках, но не сами папки. Попробуйте создать папку для архивирования файлов при поиске файлов в подкаталоге.
Вы можете посмотреть на этот ответ:
https://stackoverflow.com/a/2598649/1819900
Как насчет утилит, предоставляемых QuaZip?
http://quazip.sourceforge.net/classJlCompress.html
При создании объекта QuaZipNewInfo укажите путь и имя файла для вашего файла, так как вы хотите сохранить его в zip-файле в качестве первого аргумента, а путь и имя файла для вашего файла на диске в качестве второго аргумента. Пример:
Добавление C: /test/myFile.txt как Тест / Myfile.txt в zip:
QuaZipNewInfo("test/myFile.txt", "C:/test/myFile.txt")
Чтобы создать папку в вашем zip-файле, вам нужно создать пустой файл с именем, заканчивающимся на «/». Ответ не включает в себя список файлов / папок, но сосредоточен на создании папок в zip-файле.
QDir sourceRootDir("/path/to/source/folder");
QStringList sourceFilesList; // list of path relative to source root folder
sourceFilesList << "relativePath.txt" << "folder" << "folder/relativePath";
QualZip zip("path/to/zip.zip");
if(!zip.open(QuaZip::mdCreate)){
return false;
}
QuaZipFile outZipFile(&zip);
// Copy file and folder to zip file
foreach (const QString &sourceFilePath, sourceFilesList) {
QFileInfo sourceFI(sourceRootDir.absoluteFilePath(sourceFilePath));// FOLDER (this is the part that interests you!!!)
if(sourceFI.isFolder()){
QString sourceFolderPath = sourceFilePath;
if(!sourceFolderPath.endsWith("/")){
sourceFolderPath.append("/");
}
if(!outZipFile.open(QIODevice::WriteOnly, QuaZipNewInfo(sourceFolderPath, sourceFI.absoluteFilePath()))){
return false;
}
outZipFile.close();// FILE
} else if(sourceFI.isFile()){
QFile inFile(sourceFI.absoluteFilePath());
if(!inFile.open(QIODevice::ReadOnly)){
zip.close();
return false;
}
// Note: since relative, source=dst
if(!outZipFile.open(QIODevice::WriteOnly, QuaZipNewInfo(sourceFilePath, sourceFI.absoluteFilePath()))){
inFile.close();
zip.close();
return false;
}
// Copy
qDebug() << " copy start";
QByteArray buffer;
int chunksize = 256; // Whatever chunk size you like
buffer = inFile.read(chunksize);
while(!buffer.isEmpty()){
qDebug() << " copy " << buffer.count();
outZipFile.write(buffer);
buffer = inFile.read(chunksize);
}
outZipFile.close();
inFile.close();
} else {
// Probably simlink, ignore
}
}
zip.close();
return true;