misc/quazip/JlCompress.cpp
changeset 5752 ea95ee97c805
equal deleted inserted replaced
5750:6bbf7aee2cdf 5752:ea95ee97c805
       
     1 #include "JlCompress.h"
       
     2 #include <QDebug>
       
     3 /**OK
       
     4  * Comprime il file fileName, nell'oggetto zip, con il nome fileDest.
       
     5  *
       
     6  * La funzione fallisce se:
       
     7  * * zip==NULL;
       
     8  * * l'oggetto zip è stato aperto in una modalità non compatibile con l'aggiunta di file;
       
     9  * * non è possibile aprire il file d'origine;
       
    10  * * non è possibile creare il file all'interno dell'oggetto zip;
       
    11  * * si è rilevato un errore nella copia dei dati;
       
    12  * * non è stato possibile chiudere il file all'interno dell'oggetto zip;
       
    13  */
       
    14 bool JlCompress::compressFile(QuaZip* zip, QString fileName, QString fileDest) {
       
    15     // zip: oggetto dove aggiungere il file
       
    16     // fileName: nome del file reale
       
    17     // fileDest: nome del file all'interno del file compresso
       
    18 
       
    19     // Controllo l'apertura dello zip
       
    20     if (!zip) return false;
       
    21     if (zip->getMode()!=QuaZip::mdCreate &&
       
    22         zip->getMode()!=QuaZip::mdAppend &&
       
    23         zip->getMode()!=QuaZip::mdAdd) return false;
       
    24 
       
    25     // Apro il file originale
       
    26     QFile inFile;
       
    27     inFile.setFileName(fileName);
       
    28     if(!inFile.open(QIODevice::ReadOnly)) return false;
       
    29 
       
    30     // Apro il file risulato
       
    31     QuaZipFile outFile(zip);
       
    32     if(!outFile.open(QIODevice::WriteOnly, QuaZipNewInfo(fileDest, inFile.fileName()))) return false;
       
    33 
       
    34     // Copio i dati
       
    35     char c;
       
    36     while(inFile.getChar(&c)&&outFile.putChar(c));
       
    37     if(outFile.getZipError()!=UNZ_OK) return false;
       
    38 
       
    39     // Chiudo i file
       
    40     outFile.close();
       
    41     if (outFile.getZipError()!=UNZ_OK) return false;
       
    42     inFile.close();
       
    43 
       
    44     return true;
       
    45 }
       
    46 
       
    47 /**OK
       
    48  * Comprime la cartella dir nel file fileCompressed, se recursive è true allora
       
    49  * comprime anche le sotto cartelle. I nomi dei file preceduti dal path creato
       
    50  * togliendo il pat della cartella origDir al path della cartella dir.
       
    51  * Se la funzione fallisce restituisce false e cancella il file che si è tentato
       
    52  * di creare.
       
    53  *
       
    54  * La funzione fallisce se:
       
    55  * * zip==NULL;
       
    56  * * l'oggetto zip è stato aperto in una modalità non compatibile con l'aggiunta di file;
       
    57  * * la cartella dir non esiste;
       
    58  * * la compressione di una sotto cartella fallisce (1);
       
    59  * * la compressione di un file fallisce;
       
    60  * (1) La funzione si richiama in maniera ricorsiva per comprimere le sotto cartelle
       
    61  * dunque gli errori di compressione di una sotto cartella sono gli stessi di questa
       
    62  * funzione.
       
    63  */
       
    64 bool JlCompress::compressSubDir(QuaZip* zip, QString dir, QString origDir, bool recursive) {
       
    65     // zip: oggetto dove aggiungere il file
       
    66     // dir: cartella reale corrente
       
    67     // origDir: cartella reale originale
       
    68     // (path(dir)-path(origDir)) = path interno all'oggetto zip
       
    69 
       
    70     // Controllo l'apertura dello zip
       
    71     if (!zip) return false;
       
    72     if (zip->getMode()!=QuaZip::mdCreate &&
       
    73         zip->getMode()!=QuaZip::mdAppend &&
       
    74         zip->getMode()!=QuaZip::mdAdd) return false;
       
    75 
       
    76     // Controllo la cartella
       
    77     QDir directory(dir);
       
    78     if (!directory.exists()) return false;
       
    79 
       
    80     // Se comprimo anche le sotto cartelle
       
    81     if (recursive) {
       
    82         // Per ogni sotto cartella
       
    83         QFileInfoList files = directory.entryInfoList(QDir::AllDirs|QDir::NoDotAndDotDot);
       
    84         foreach (QFileInfo file, files) {
       
    85             // Comprimo la sotto cartella
       
    86             if(!compressSubDir(zip,file.absoluteFilePath(),origDir,recursive)) return false;
       
    87         }
       
    88     }
       
    89 
       
    90     // Per ogni file nella cartella
       
    91     QFileInfoList files = directory.entryInfoList(QDir::Files);
       
    92     QDir origDirectory(origDir);
       
    93     foreach (QFileInfo file, files) {
       
    94         // Se non è un file o è il file compresso che sto creando
       
    95         if(!file.isFile()||file.absoluteFilePath()==zip->getZipName()) continue;
       
    96 
       
    97         // Creo il nome relativo da usare all'interno del file compresso
       
    98         QString filename = origDirectory.relativeFilePath(file.absoluteFilePath());
       
    99 
       
   100         // Comprimo il file
       
   101         if (!compressFile(zip,file.absoluteFilePath(),filename)) return false;
       
   102     }
       
   103 
       
   104     return true;
       
   105 }
       
   106 
       
   107 /**OK
       
   108  * Estrae il file fileName, contenuto nell'oggetto zip, con il nome fileDest.
       
   109  * Se la funzione fallisce restituisce false e cancella il file che si è tentato di estrarre.
       
   110  *
       
   111  * La funzione fallisce se:
       
   112  * * zip==NULL;
       
   113  * * l'oggetto zip è stato aperto in una modalità non compatibile con l'estrazione di file;
       
   114  * * non è possibile aprire il file all'interno dell'oggetto zip;
       
   115  * * non è possibile creare il file estratto;
       
   116  * * si è rilevato un errore nella copia dei dati (1);
       
   117  * * non è stato possibile chiudere il file all'interno dell'oggetto zip (1);
       
   118  *
       
   119  * (1): prima di uscire dalla funzione cancella il file estratto.
       
   120  */
       
   121 bool JlCompress::extractFile(QuaZip* zip, QString fileName, QString fileDest) {
       
   122     // zip: oggetto dove aggiungere il file
       
   123     // filename: nome del file reale
       
   124     // fileincompress: nome del file all'interno del file compresso
       
   125 
       
   126     // Controllo l'apertura dello zip
       
   127     if (!zip) return false;
       
   128     if (zip->getMode()!=QuaZip::mdUnzip) return false;
       
   129 
       
   130     // Apro il file compresso
       
   131     zip->setCurrentFile(fileName);
       
   132     QuaZipFile inFile(zip);
       
   133     if(!inFile.open(QIODevice::ReadOnly) || inFile.getZipError()!=UNZ_OK) return false;
       
   134 
       
   135     // Controllo esistenza cartella file risultato
       
   136     QDir().mkpath(QFileInfo(fileDest).absolutePath());
       
   137 
       
   138     // Apro il file risultato
       
   139     QFile outFile;
       
   140     outFile.setFileName(fileDest);
       
   141     if(!outFile.open(QIODevice::WriteOnly)) return false;
       
   142 
       
   143     // Copio i dati
       
   144     char c;
       
   145     while(inFile.getChar(&c)) outFile.putChar(c);
       
   146     if (inFile.getZipError()!=UNZ_OK) {
       
   147         removeFile(QStringList(fileDest));
       
   148         return false;
       
   149     }
       
   150 
       
   151     // Chiudo i file
       
   152     inFile.close();
       
   153     if (inFile.getZipError()!=UNZ_OK) {
       
   154         removeFile(QStringList(fileDest));
       
   155         return false;
       
   156     }
       
   157     outFile.close();
       
   158 
       
   159     return true;
       
   160 }
       
   161 
       
   162 /**
       
   163  * Rimuove i file il cui nome è specificato all'interno di listFile.
       
   164  * Restituisce true se tutti i file sono stati cancellati correttamente, attenzione
       
   165  * perchè può restituire false anche se alcuni file non esistevano e si è tentato
       
   166  * di cancellarli.
       
   167  */
       
   168 bool JlCompress::removeFile(QStringList listFile) {
       
   169     bool ret = true;
       
   170     // Per ogni file
       
   171     for (int i=0; i<listFile.count(); i++) {
       
   172         // Lo elimino
       
   173         ret = ret && QFile::remove(listFile.at(i));
       
   174     }
       
   175     return ret;
       
   176 }
       
   177 
       
   178 ////////////////////////////////////////////////////////////////////////////////
       
   179 ////////////////////////////////////////////////////////////////////////////////
       
   180 /**OK
       
   181  * Comprime il file fileName nel file fileCompressed.
       
   182  * Se la funzione fallisce restituisce false e cancella il file che si è tentato
       
   183  * di creare.
       
   184  *
       
   185  * La funzione fallisce se:
       
   186  * * non si riesce ad aprire l'oggetto zip;
       
   187  * * la compressione del file fallisce;
       
   188  * * non si riesce a chiudere l'oggetto zip;
       
   189  */
       
   190 bool JlCompress::compressFile(QString fileCompressed, QString file) {
       
   191     // Creo lo zip
       
   192     QuaZip* zip  = new QuaZip(QFileInfo(fileCompressed).absoluteFilePath());
       
   193     QDir().mkpath(QFileInfo(fileCompressed).absolutePath());
       
   194     if(!zip->open(QuaZip::mdCreate)) {
       
   195         delete zip;
       
   196         QFile::remove(fileCompressed);
       
   197         return false;
       
   198     }
       
   199 
       
   200     // Aggiungo il file
       
   201     if (!compressFile(zip,file,QFileInfo(file).fileName())) {
       
   202         delete zip;
       
   203         QFile::remove(fileCompressed);
       
   204         return false;
       
   205     }
       
   206 
       
   207     // Chiudo il file zip
       
   208     zip->close();
       
   209     if(zip->getZipError()!=0) {
       
   210         delete zip;
       
   211         QFile::remove(fileCompressed);
       
   212         return false;
       
   213     }
       
   214     delete zip;
       
   215 
       
   216     return true;
       
   217 }
       
   218 
       
   219 /**OK
       
   220  * Comprime i file specificati in files nel file fileCompressed.
       
   221  * Se la funzione fallisce restituisce false e cancella il file che si è tentato
       
   222  * di creare.
       
   223  *
       
   224  * La funzione fallisce se:
       
   225  * * non si riesce ad aprire l'oggetto zip;
       
   226  * * la compressione di un file fallisce;
       
   227  * * non si riesce a chiudere l'oggetto zip;
       
   228  */
       
   229 bool JlCompress::compressFiles(QString fileCompressed, QStringList files) {
       
   230     // Creo lo zip
       
   231     QuaZip* zip  = new QuaZip(QFileInfo(fileCompressed).absoluteFilePath());
       
   232     QDir().mkpath(QFileInfo(fileCompressed).absolutePath());
       
   233     if(!zip->open(QuaZip::mdCreate)) {
       
   234         delete zip;
       
   235         QFile::remove(fileCompressed);
       
   236         return false;
       
   237     }
       
   238 
       
   239     // Comprimo i file
       
   240     QFileInfo info;
       
   241     foreach (QString file, files) {
       
   242         info.setFile(file);
       
   243         if (!info.exists() || !compressFile(zip,file,info.fileName())) {
       
   244             delete zip;
       
   245             QFile::remove(fileCompressed);
       
   246             return false;
       
   247         }
       
   248     }
       
   249 
       
   250     // Chiudo il file zip
       
   251     zip->close();
       
   252     if(zip->getZipError()!=0) {
       
   253         delete zip;
       
   254         QFile::remove(fileCompressed);
       
   255         return false;
       
   256     }
       
   257     delete zip;
       
   258 
       
   259     return true;
       
   260 }
       
   261 
       
   262 /**OK
       
   263  * Comprime la cartella dir nel file fileCompressed, se recursive è true allora
       
   264  * comprime anche le sotto cartelle.
       
   265  * Se la funzione fallisce restituisce false e cancella il file che si è tentato
       
   266  * di creare.
       
   267  *
       
   268  * La funzione fallisce se:
       
   269  * * non si riesce ad aprire l'oggetto zip;
       
   270  * * la compressione di un file fallisce;
       
   271  * * non si riesce a chiudere l'oggetto zip;
       
   272  */
       
   273 bool JlCompress::compressDir(QString fileCompressed, QString dir, bool recursive) {
       
   274     // Creo lo zip
       
   275     QuaZip* zip  = new QuaZip(QFileInfo(fileCompressed).absoluteFilePath());
       
   276     QDir().mkpath(QFileInfo(fileCompressed).absolutePath());
       
   277     if(!zip->open(QuaZip::mdCreate)) {
       
   278         delete zip;
       
   279         QFile::remove(fileCompressed);
       
   280         return false;
       
   281     }
       
   282 
       
   283     // Aggiungo i file e le sotto cartelle
       
   284     if (!compressSubDir(zip,dir,dir,recursive)<0) {
       
   285         delete zip;
       
   286         QFile::remove(fileCompressed);
       
   287         return false;
       
   288     }
       
   289 
       
   290     // Chiudo il file zip
       
   291     zip->close();
       
   292     if(zip->getZipError()!=0) {
       
   293         delete zip;
       
   294         QFile::remove(fileCompressed);
       
   295         return false;
       
   296     }
       
   297     delete zip;
       
   298 
       
   299     return true;
       
   300 }
       
   301 
       
   302 ////////////////////////////////////////////////////////////////////////////////
       
   303 ////////////////////////////////////////////////////////////////////////////////
       
   304 /**OK
       
   305  * Estrae il file fileName, contenuto nel file fileCompressed, con il nome fileDest.
       
   306  * Se fileDest = "" allora il file viene estratto con lo stesso nome con cui è
       
   307  * stato compresso.
       
   308  * Se la funzione fallisce cancella il file che si è tentato di estrarre.
       
   309  * Restituisce il nome assoluto del file estratto.
       
   310  *
       
   311  * La funzione fallisce se:
       
   312  * * non si riesce ad aprire l'oggetto zip;
       
   313  * * l'estrazione del file fallisce;
       
   314  * * non si riesce a chiudere l'oggetto zip;
       
   315  */
       
   316 QString JlCompress::extractFile(QString fileCompressed, QString fileName, QString fileDest) {
       
   317     // Apro lo zip
       
   318     QuaZip* zip  = new QuaZip(QFileInfo(fileCompressed).absoluteFilePath());
       
   319     if(!zip->open(QuaZip::mdUnzip)) {
       
   320         delete zip;
       
   321         return QString();
       
   322     }
       
   323 
       
   324     // Estraggo il file
       
   325     if (fileDest.isEmpty()) fileDest = fileName;
       
   326     if (!extractFile(zip,fileName,fileDest)) {
       
   327         delete zip;
       
   328         return QString();
       
   329     }
       
   330 
       
   331     // Chiudo il file zip
       
   332     zip->close();
       
   333     if(zip->getZipError()!=0) {
       
   334         removeFile(QStringList(fileDest));
       
   335         return QString();
       
   336     }
       
   337     delete zip;
       
   338 
       
   339     return QFileInfo(fileDest).absoluteFilePath();
       
   340 }
       
   341 
       
   342 /**OK
       
   343  * Estrae i file specificati in files, contenuti nel file fileCompressed, nella
       
   344  * cartella dir. La struttura a cartelle del file compresso viene rispettata.
       
   345  * Se dir = "" allora il file viene estratto nella cartella corrente.
       
   346  * Se la funzione fallisce cancella i file che si è tentato di estrarre.
       
   347  * Restituisce i nomi assoluti dei file estratti.
       
   348  *
       
   349  * La funzione fallisce se:
       
   350  * * non si riesce ad aprire l'oggetto zip;
       
   351  * * l'estrazione di un file fallisce;
       
   352  * * non si riesce a chiudere l'oggetto zip;
       
   353  */
       
   354 QStringList JlCompress::extractFiles(QString fileCompressed, QStringList files, QString dir) {
       
   355     // Creo lo zip
       
   356     QuaZip* zip  = new QuaZip(QFileInfo(fileCompressed).absoluteFilePath());
       
   357     if(!zip->open(QuaZip::mdUnzip)) {
       
   358         delete zip;
       
   359         return QStringList();
       
   360     }
       
   361 
       
   362     // Estraggo i file
       
   363     for (int i=0; i<files.count(); i++) {
       
   364         if (!extractFile(zip, files.at(i), QDir(dir).absoluteFilePath(files.at(i)))) {
       
   365             delete zip;
       
   366             removeFile(files);
       
   367             return QStringList();
       
   368         }
       
   369         files[i] = QDir(dir).absoluteFilePath(files.at(i));
       
   370     }
       
   371 
       
   372     // Chiudo il file zip
       
   373     zip->close();
       
   374     if(zip->getZipError()!=0) {
       
   375         delete zip;
       
   376         removeFile(files);
       
   377         return QStringList();
       
   378     }
       
   379     delete zip;
       
   380 
       
   381     return files;
       
   382 }
       
   383 
       
   384 /**OK
       
   385  * Estrae il file fileCompressed nella cartella dir.
       
   386  * Se dir = "" allora il file viene estratto nella cartella corrente.
       
   387  * Se la funzione fallisce cancella i file che si è tentato di estrarre.
       
   388  * Restituisce i nomi assoluti dei file estratti.
       
   389  *
       
   390  * La funzione fallisce se:
       
   391  * * non si riesce ad aprire l'oggetto zip;
       
   392  * * la compressione di un file fallisce;
       
   393  * * non si riesce a chiudere l'oggetto zip;
       
   394  */
       
   395 QStringList JlCompress::extractDir(QString fileCompressed, QString dir) {
       
   396     // Apro lo zip
       
   397     QuaZip* zip = new QuaZip(QFileInfo(fileCompressed).absoluteFilePath());
       
   398     if(!zip->open(QuaZip::mdUnzip)) {
       
   399         delete zip;
       
   400         return QStringList();
       
   401     }
       
   402 
       
   403     // Estraggo i file
       
   404     QStringList lst = getFileList(fileCompressed);
       
   405 
       
   406     QDir directory(dir);
       
   407     for (int i=0; i<lst.count(); i++) {
       
   408         QString absFilePath = directory.absoluteFilePath(lst.at(i));
       
   409         if (!extractFile(zip, lst.at(i), absFilePath)) {
       
   410             delete zip;
       
   411             removeFile(lst);
       
   412             return QStringList();
       
   413         }
       
   414         lst[i] = absFilePath;
       
   415     }
       
   416 
       
   417     // Chiudo il file zip
       
   418     zip->close();
       
   419     if(zip->getZipError()!=0) {
       
   420         delete zip;
       
   421         removeFile(lst);
       
   422         return QStringList();
       
   423     }
       
   424     delete zip;
       
   425 
       
   426     return lst;
       
   427 }
       
   428 
       
   429 /**OK
       
   430  * Restituisce la lista dei file resenti nel file compresso fileCompressed.
       
   431  * Se la funzione fallisce, restituisce un elenco vuoto.
       
   432  *
       
   433  * La funzione fallisce se:
       
   434  * * non si riesce ad aprire l'oggetto zip;
       
   435  * * la richiesta di informazioni di un file fallisce;
       
   436  * * non si riesce a chiudere l'oggetto zip;
       
   437  */
       
   438 QStringList JlCompress::getFileList(QString fileCompressed) {
       
   439     // Apro lo zip
       
   440     QuaZip* zip = new QuaZip(QFileInfo(fileCompressed).absoluteFilePath());
       
   441     if(!zip->open(QuaZip::mdUnzip)) {
       
   442         delete zip;
       
   443         return QStringList();
       
   444     }
       
   445 
       
   446     // Estraggo i nomi dei file
       
   447     QStringList lst;
       
   448     QuaZipFileInfo info;
       
   449     for(bool more=zip->goToFirstFile(); more; more=zip->goToNextFile()) {
       
   450       if(!zip->getCurrentFileInfo(&info)) {
       
   451           delete zip;
       
   452           return QStringList();
       
   453       }
       
   454       lst << info.name;
       
   455       //info.name.toLocal8Bit().constData()
       
   456     }
       
   457 
       
   458     // Chiudo il file zip
       
   459     zip->close();
       
   460     if(zip->getZipError()!=0) {
       
   461         delete zip;
       
   462         return QStringList();
       
   463     }
       
   464     delete zip;
       
   465 
       
   466     return lst;
       
   467 }
       
   468