2010-04-08 4 views
11

mit ich würde gerne wissen, ob wir jede Klasse in qt haben, die einen Ordner oder file.i qprocess verwendet zip kann zu komprimieren, wurde es komprimiert, aber ich bin nicht in der Lage, es zu dekomprimieren normalen Zip-Tool .can jemand lassen Sie mich wissen, wie können wir einen Ordner/Datei mit qt api Klassenzippen einen Ordner/Datei qt

Antwort

4

ich Sie können nicht denken, zu komprimieren. Soweit ich weiß, bieten qcompress und quncompress nur das Komprimieren von Streams usw. Das bedeutet, dass sie nicht die Header erstellen, die für eine echte Zip-Datei benötigt werden (die auch angibt, welche Dateien in der Datei enthalten sind).

Allerdings gibt es eine Open-Source-Qt-Bibliothek namens QuaZip die zlib verwendet (kommt mit qt) und bietet genau das.

25

Vor ein paar Jahren hatte ich eine solche Frage, und hier ist meine Lösung:

1). QuaZip bekommen (hier ist die link text)

2). umfassen quazip Quellen zu einem Projekt

Header-Datei:

HEADERS += src/quazip/crypt.h \ 
      src/quazip/ioapi.h \ 
      src/quazip/quazip.h \ 
      src/quazip/quazipfile.h \ 
      src/quazip/quazipfileinfo.h \ 
      src/quazip/quazipnewinfo.h \ 
      src/quazip/unzip.h \ 
      src/quazip/zip.h \ 
      ... 

Quellen:

SOURCES += src/quazip/ioapi.c \ 
      src/quazip/quazip.cpp \ 
      src/quazip/quazipfile.cpp \ 
      src/quazip/quazipnewinfo.cpp \ 
      src/quazip/unzip.c \ 
      src/quazip/zip.c 
      ... 

3). Kopfzeilen hinzufügen

#include "quazip/quazip.h" 
#include "quazip/quazipfile.h" 

4). verwenden Extrakt Funktion:

static bool extract(const QString & filePath, const QString & extDirPath, const QString & singleFileName = QString("")) { 

QuaZip zip(filePath); 

if (!zip.open(QuaZip::mdUnzip)) { 
    qWarning("testRead(): zip.open(): %d", zip.getZipError()); 
    return false; 
} 

zip.setFileNameCodec("IBM866"); 

qWarning("%d entries\n", zip.getEntriesCount()); 
qWarning("Global comment: %s\n", zip.getComment().toLocal8Bit().constData()); 

QuaZipFileInfo info; 

QuaZipFile file(&zip); 

QFile out; 
QString name; 
char c; 
for (bool more = zip.goToFirstFile(); more; more = zip.goToNextFile()) { 

    if (!zip.getCurrentFileInfo(&info)) { 
     qWarning("testRead(): getCurrentFileInfo(): %d\n", zip.getZipError()); 
     return false; 
    } 

    if (!singleFileName.isEmpty()) 
     if (!info.name.contains(singleFileName)) 
      continue; 

    if (!file.open(QIODevice::ReadOnly)) { 
     qWarning("testRead(): file.open(): %d", file.getZipError()); 
     return false; 
    } 

    name = QString("%1/%2").arg(extDirPath).arg(file.getActualFileName()); 

    if (file.getZipError() != UNZ_OK) { 
     qWarning("testRead(): file.getFileName(): %d", file.getZipError()); 
     return false; 
    } 

    //out.setFileName("out/" + name); 
    out.setFileName(name); 

    // this will fail if "name" contains subdirectories, but we don't mind that 
    out.open(QIODevice::WriteOnly); 
    // Slow like hell (on GNU/Linux at least), but it is not my fault. 
    // Not ZIP/UNZIP package's fault either. 
    // The slowest thing here is out.putChar(c). 
    while (file.getChar(&c)) out.putChar(c); 

    out.close(); 

    if (file.getZipError() != UNZ_OK) { 
     qWarning("testRead(): file.getFileName(): %d", file.getZipError()); 
     return false; 
    } 

    if (!file.atEnd()) { 
     qWarning("testRead(): read all but not EOF"); 
     return false; 
    } 

    file.close(); 

    if (file.getZipError() != UNZ_OK) { 
     qWarning("testRead(): file.close(): %d", file.getZipError()); 
     return false; 
    } 
} 

zip.close(); 

if (zip.getZipError() != UNZ_OK) { 
    qWarning("testRead(): zip.close(): %d", zip.getZipError()); 
    return false; 
} 

return true; 
} 

und Archivfunktion:

static bool archive(const QString & filePath, const QDir & dir, const QString & comment = QString("")) { 

QuaZip zip(filePath); 
zip.setFileNameCodec("IBM866"); 

if (!zip.open(QuaZip::mdCreate)) { 
    myMessageOutput(true, QtDebugMsg, QString("testCreate(): zip.open(): %1").arg(zip.getZipError())); 
    return false; 
} 

if (!dir.exists()) { 
    myMessageOutput(true, QtDebugMsg, QString("dir.exists(%1)=FALSE").arg(dir.absolutePath())); 
    return false; 
} 

QFile inFile; 

// Получаем список файлов и папок рекурсивно 
QStringList sl; 
recurseAddDir(dir, sl); 

// Создаем массив состоящий из QFileInfo объектов 
QFileInfoList files; 
foreach (QString fn, sl) files << QFileInfo(fn); 

QuaZipFile outFile(&zip); 

char c; 
foreach(QFileInfo fileInfo, files) { 

    if (!fileInfo.isFile()) 
     continue; 

    // Если файл в поддиректории, то добавляем имя этой поддиректории к именам файлов 
    // например: fileInfo.filePath() = "D:\Work\Sources\SAGO\svn\sago\Release\tmp_DOCSWIN\Folder\123.opn" 
    // тогда после удаления части строки fileNameWithSubFolders будет равен "Folder\123.opn" и т.д. 
    QString fileNameWithRelativePath = fileInfo.filePath().remove(0, dir.absolutePath().length() + 1); 

    inFile.setFileName(fileInfo.filePath()); 

    if (!inFile.open(QIODevice::ReadOnly)) { 
     myMessageOutput(true, QtDebugMsg, QString("testCreate(): inFile.open(): %1").arg(inFile.errorString().toLocal8Bit().constData())); 
     return false; 
    } 

    if (!outFile.open(QIODevice::WriteOnly, QuaZipNewInfo(fileNameWithRelativePath, fileInfo.filePath()))) { 
     myMessageOutput(true, QtDebugMsg, QString("testCreate(): outFile.open(): %1").arg(outFile.getZipError())); 
     return false; 
    } 

    while (inFile.getChar(&c) && outFile.putChar(c)); 

    if (outFile.getZipError() != UNZ_OK) { 
     myMessageOutput(true, QtDebugMsg, QString("testCreate(): outFile.putChar(): %1").arg(outFile.getZipError())); 
     return false; 
    } 

    outFile.close(); 

    if (outFile.getZipError() != UNZ_OK) { 
     myMessageOutput(true, QtDebugMsg, QString("testCreate(): outFile.close(): %1").arg(outFile.getZipError())); 
     return false; 
    } 

    inFile.close(); 
} 

// + комментарий 
if (!comment.isEmpty()) 
    zip.setComment(comment); 

zip.close(); 

if (zip.getZipError() != 0) { 
    myMessageOutput(true, QtDebugMsg, QString("testCreate(): zip.close(): %1").arg(zip.getZipError())); 
    return false; 
} 

return true; 
} 

5). genießen;)

UPDATE: für CapDroid.

/* Рекурсивно ищет все файлы в директории \a и добавляет в список \b */ 
static void recurseAddDir(QDir d, QStringList & list) { 

    QStringList qsl = d.entryList(QDir::NoDotAndDotDot | QDir::Dirs | QDir::Files); 

    foreach (QString file, qsl) { 

     QFileInfo finfo(QString("%1/%2").arg(d.path()).arg(file)); 

     if (finfo.isSymLink()) 
      return; 

     if (finfo.isDir()) { 

      QString dirname = finfo.fileName(); 
      QDir sd(finfo.filePath()); 

      recurseAddDir(sd, list); 

     } else 
      list << QDir::toNativeSeparators(finfo.filePath()); 
    } 
} 
+0

können Sie fügen Sie bitte ** recurseAddDir (dir, sl); ** diese Methode in Antwort .... –

+0

@CapDroid fertig! – mosg

+0

@moseg danke, Bruder .. lassen Sie mich überprüfen –