2010-04-08 40 views
11

tôi muốn biết nếu chúng tôi có bất kỳ lớp nào trong qt có thể nén một thư mục hoặc tệp.i đã sử dụng qprocess để nén, nó đã được nén nhưng tôi không thể giải nén nó bằng công cụ zip thông thường .có thể cho tôi biết cách chúng tôi có thể nén thư mục/tệp bằng các lớp qt apinén một thư mục/tập tin bằng cách sử dụng qt

Trả lời

4

Tôi không nghĩ bạn có thể. Theo như tôi biết qcompress và quncompress chỉ cung cấp nén các dòng vv Điều này có nghĩa là họ sẽ không tạo ra các tiêu đề cần thiết cho một zipfile thực (mà còn nói những tập tin có trong tập tin).

Tuy nhiên, có một thư viện Qt nguồn mở được gọi là QuaZip sử dụng zlib (đi kèm với qt) và chỉ cung cấp.

25

Một vài năm trước, tôi có vấn đề như vậy và đây là giải pháp của tôi:

1). nhận QuaZip (ở đây là link text)

2). bao gồm các nguồn quazip đến tập tin của bạn dự án

Headers:

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

Nguồn:

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). thêm tiêu đề

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

4). sử dụng chức năng chiết xuất:

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

và lưu trữ chức năng:

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). thưởng thức;)

CẬP NHẬT: cho 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

bạn có thể thêm ** recurseAddDir (dir, sl); ** phương thức này vào câu trả lời .... –

+0

@CapDroid đã hoàn tất! – mosg

+0

@moseg cảm ơn, anh .. hãy để tôi kiểm tra –

Các vấn đề liên quan