2010-04-08 13 views
11

me gustaría saber si tenemos alguna clase en qt que pueda comprimir una carpeta o un archivo.i usé qprocess para comprimir, se comprimió pero no puedo descomprimirlo usando la herramienta zip normal . ¿Alguien me puede dejar saber cómo podemos comprimir una carpeta/archivo usando qt api classescomprimir una carpeta/archivo usando qt

Respuesta

4

No creo que se pueda. Por lo que sé, qcompress y quncompress solo proporcionan compresión de flujos, etc. Esto significa que no crearán los encabezados necesarios para un archivo zip real (que también indica qué archivos están en el archivo).

Sin embargo, hay una biblioteca de código abierto Qt llamada QuaZip que utiliza zlib (viene con qt) y proporciona precisamente eso. Hace

25

unos años tuve un problema de este tipo, y aquí está mi solución:

1). obtener QuaZip (aquí está el link text)

2). incluir fuentes quazip a su archivo de proyecto

encabezados:

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 \ 
      ... 

Fuentes:

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). agregar encabezados

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

4). utilizar la función de extracto:

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; 
} 

y archivo función:

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). disfrutar;)

ACTUALIZACIÓN: para 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

puede usted por favor añadir ** recurseAddDir (dir, sl); ** este método en respuesta .... –

+0

@CapDroid hecho! – mosg

+0

@moseg gracias, hermano ... déjame ver –

Cuestiones relacionadas