Wie verwende ich Minizip (auf Zlib)?

Lesezeit: 5 Minuten

Benutzer-Avatar
JellicleCat

Ich versuche, Dateien für eine plattformübergreifende Anwendung zu archivieren, und es sieht so aus, als wäre Minizip (auf zlib aufgebaut) ungefähr so ​​portabel wie Archivierer.

Wenn ich jedoch versuche, den folgenden Dummy-Code auszuführen, erhalte ich einen Systemfehler [my executable] has stopped working. Windows can check online for a solution to the problem.

Kann mir jemand helfen, wie ich diese Bibliothek verwende? — (es gibt nirgendwo ein Dokument oder Tutorial, das ich finden kann)

zip_fileinfo zfi;

int main()
{
    zipFile zf = zipOpen("myarch.zip",APPEND_STATUS_ADDINZIP);
    int ret = zipOpenNewFileInZip(zf,
        "myfile.txt",
        &zfi,
        NULL,   0,
        NULL,   0,
        "my comment for this interior file",
        Z_DEFLATED,
        Z_NO_COMPRESSION
        );
    zipCloseFileInZip(zf);
    zipClose(zf, "my comment for exterior file");
    return 0;
}

Spezifikationen: Msys + MinGW, Windows 7, mit zlibwapi.dll aus zlib125dll.zip/dll32

Benutzer-Avatar
Niemiro

Da ich diese Frage über Google gefunden habe und keinen vollständigen, funktionierenden Code enthielt, stelle ich hier einigen für zukünftige Besucher zur Verfügung.

int CreateZipFile (std::vector<wstring> paths)
{
    zipFile zf = zipOpen(std::string(destinationPath.begin(), destinationPath.end()).c_str(), APPEND_STATUS_CREATE);
    if (zf == NULL)
        return 1;

    bool _return = true;
    for (size_t i = 0; i < paths.size(); i++)
    {
        std::fstream file(paths[i].c_str(), std::ios::binary | std::ios::in);
        if (file.is_open())
        {
            file.seekg(0, std::ios::end);
            long size = file.tellg();
            file.seekg(0, std::ios::beg);

            std::vector<char> buffer(size);
            if (size == 0 || file.read(&buffer[0], size))
            {
                zip_fileinfo zfi = { 0 };
                std::wstring fileName = paths[i].substr(paths[i].rfind('\\')+1);

                if (S_OK == zipOpenNewFileInZip(zf, std::string(fileName.begin(), fileName.end()).c_str(), &zfi, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION))
                {
                    if (zipWriteInFileInZip(zf, size == 0 ? "" : &buffer[0], size))
                        _return = false;

                    if (zipCloseFileInZip(zf))
                        _return = false;

                    file.close();
                    continue;
                }
            }
            file.close();
        }
        _return = false;
    }

    if (zipClose(zf, NULL))
        return 3;

    if (!_return)
        return 4;
    return S_OK;
}

  • Das ist gut. Ein paar Probleme jedoch: 1. Dies setzt voraus, dass die gesamte Datei in den Speicher passt, was eine etwas vereinfachte Ansicht ist, aber vielleicht gut genug für dieses Beispiel. 2. Es gibt keinen Grund, warum eine Dateiausgabe mit der Länge 0 ein Fehler ist, wenn die anfängliche Dateilänge 0 ist. 3. Unter der Annahme, dass es sich um einen Fehler handelt, besteht keine Notwendigkeit für die ternäre Operation. dh if (zipWriteInFileInZip(zf, size == 0 ? "" : &buffer[0], size)) kann geschrieben werden als if (zipWriteInFileInZip(zf, &buffer[0], size)). 4. Ich würde empfehlen, keinen Unterstrich als Präfix zu verwenden. Ich weiß, dass du einen Kleinbuchstaben danach verwendest, aber… zucken

    – Adrian

    23. März 2016 um 17:05 Uhr


  • Der zweite und der dritte Punkt, den Sie ansprechen, sind falsch. Die Überprüfung auf size==0 soll diesen Puffer sicherstellen[0] wird nicht auf Nulllänge ausgeführt. Die logische or-Operation in der if-Anweisung stellt dann sicher, dass Dateien der Länge Null korrekt in die ZIP-Datei geschrieben werden, und die spätere Ternäre soll wiederum diesen Puffer sicherstellen[0] wird nicht auf Nulllänge aufgerufen. Der Code funktioniert korrekt und wie erwartet.

    – niemiro

    10. Juni 2016 um 0:35 Uhr

  • Dies ist als C gekennzeichnet, nicht als C++.

    – Neil Roy

    14. April 2017 um 1:55 Uhr

  • Es gibt einige Tippfehler. Anstatt von S_OK (verwendet in COM) sollte man schreiben Z_OK.

    – Joghurt

    27. August 2020 um 18:42 Uhr

  • @Yogurt Eigentlich sollte ZIP_OK oder UNZ_OK von zip.h bzw. unzip.h sein.

    – RobinP

    1. Juli um 10:14 Uhr

Benutzer-Avatar
Nathan Moinvaziri

Die Minizip-Bibliothek enthält Beispiele; minizip.c zum Reißverschluss u miniunz.c zum Entpacken. Beide sind Befehlszeilenprogramme, die zeigen, wie die Bibliothek verwendet wird. Sie sind jedoch ein Durcheinander.

Sie müssen auch die zfi füllen zip_fileinfo. Zumindest sollten Sie die Struktur auf Null initialisieren. zfi enthält Informationen über die Datei, die Sie speichern möchten zipOpenNewFileInZip. Die Struktur sollte das Datum und die Attribute von “myfile.txt” enthalten.

Ich empfehle die Verwendung von PKWARE Desktop zur Diagnose von Zip-Problemen. Es zeigt die Struktur/Eigenschaften der Dateien in der ZIP-Datei und die ZIP-Datei selbst. Als ich myarch.zip öffnete, sagte es mir, dass es Fehler gab. Ich habe in die Dateieigenschaften gebohrt und festgestellt, dass die Attribute deaktiviert waren.

  • Vielen Dank für die Untersuchung, aber im obigen Codebeispiel sollte dies nicht der Fall sein zfi auf Null initialisiert werden, ohne dass ich es spezifiziert habe? Es ist auf dem Haufen, da es außerhalb jeder Funktion ist, richtig?

    – JellicleCat

    9. Juli 2012 um 14:09 Uhr


  • Ah ja, du hast recht. Ich habe Ihren Code gerade in eine Funktion geworfen, um zu sehen, ob er funktioniert.

    – Nathan Moinvaziri

    9. Juli 2012 um 17:18 Uhr


  • Ihr Code sollte dann ordnungsgemäß funktionieren. Ich habe keine Windows-Abstürze davon bekommen. Es könnte ein Problem mit der Verwendung der DLL sein. Haben Sie versucht, in der zlib-Bibliothek zu kompilieren?

    – Nathan Moinvaziri

    9. Juli 2012 um 17:22 Uhr

  • zfi befindet sich nicht auf dem Heap, bei dem es sich um dynamisch zugewiesenen Speicher handelt, wie er beispielsweise von malloc erhalten wird. Auf *NIX befindet sich zfi im BSS, das tatsächlich auf Null initialisiert wird. Konzeptionell ist alles, was das BSS-Segment in einer ausführbaren Datei angibt, seine Ladeadresse und Länge.

    – Mike Crawford

    30. August 2016 um 3:58 Uhr

Die Minizip-Bibliothek ist gut dokumentiert. Öffnen Sie einfach die zip.h für Details.

Ich kann Ihnen hier sagen, dass Sie möglicherweise einen falschen Parameter für zipOpen übergeben haben. (APPEND_STATUS_ADDINZIP erfordert eine vorhandene ZIP-Datei!)

Bitte überprüfen Sie auch, ob zipOpen ein gültiges zipFile-Handle zurückgibt.

  • Vielen Dank. Ich habe mein 2. arg auf geändert APPEND_STATUS_CREATE. Ich sehe keinen Hinweis auf Gültigkeit in zip.h; dafür soll ich mal schauen ob das zipfile ist NULL?

    – JellicleCat

    7. Juli 2012 um 17:32 Uhr

  • Darüber hinaus können Sie etwas Licht ins Dunkel bringen extrafield_local und extrafield_global sollen sein? Ich finde kein Beispiel oder keine ausreichende Beschreibung.

    – JellicleCat

    7. Juli 2012 um 18:49 Uhr


  • Ich habe noch nie extrafield_local und extrafield_global verwendet. Tut mir leid, ich kann nicht helfen. Wenn Ihre zip.h keine Dokumentation enthält, können Sie den Quellcode von zlib herunterladen. Ich bin sicher, dass zip.h in diesem Paket eine gute Dokumentation enthält.

    – Rango

    8. Juli 2012 um 11:56 Uhr

  • Ja, Sie können überprüfen, ob zf NULL ist, um festzustellen, ob es sich um ein gültiges zipFile-Handle handelt.

    – Nathan Moinvaziri

    9. Juli 2012 um 9:53 Uhr

  • Es tut mir leid, das sagen zu müssen, aber Minizip ist weit davon entfernt, gut dokumentiert zu sein. Es ist in der Tat das absolute Gegenteil.

    – Javier Quevedo

    2. November 2016 um 12:05 Uhr

1066090cookie-checkWie verwende ich Minizip (auf Zlib)?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy