Partage
  • Partager sur Facebook
  • Partager sur Twitter

Lib Zip / Unzip en mémoire

Sujet résolu
    26 octobre 2018 à 21:46:30

    Hello ! :)

    Après plusieurs jours de recherche, je désespère complètement de ne pas trouver de lib simple pour zipper / unzipper un fichier en C++ sous Windows avec msvc, avec licence libre (LGPL de préférence).

    J'ai besoin d'aller modifier des fichiers dans une archive (changer des valeurs dans un xlsx en fait).

    J'ai tenté plusieurs trucs :

    • 7z : Le SDK LZMA n'a aucune doc, aucune explication sur la compilation. Si on prend les sources de 7zip et le dll installé sur la machine, il manque quand même une doc pour nous dire quels objets utiliser. Très mal foutu.
    • libarchive : J'ai réussi à compiler pour visual, fait marcher le truc mais j'ai des erreurs de deflate. La librairie ne doit pas le gérer.
    • Libzippp : J'ai réussi à compiler pour visual, mais le link ne semble pas marcher avec ce compilo.
    • Minizip : J'ai eu du mal à comprendre, il faut aussi zlib, j'ai du mal à comprendre les instructions pour faire le lien entre les deux
    • QuaZIP : Je n'ai pas trop eu le temps de creuser encore, mais il faut lier ça avec zlib. Il faut l'installer ou faire ça avec les sources ?

    Bref, j'imagine qu'être sur Windows n'aide pas trop et qu'à force d'avoir le nez dedans j'ai un peu de mal mais si vous pouviez m'éclairer un peu sur ce sujet. :)

    Merci. ;)

    • Partager sur Facebook
    • Partager sur Twitter
      26 octobre 2018 à 21:50:57

      Et pourquoi ne pas installer 7z sur ta machine et l'appeler par ligne de commande ?
      • Partager sur Facebook
      • Partager sur Twitter
        26 octobre 2018 à 21:55:21

        C'est pour un truc qui sera distribué, on ne peut pas imposer l'installation de 7z. :/
        • Partager sur Facebook
        • Partager sur Twitter
          26 octobre 2018 à 21:58:02

          https://portableapps.com/apps/utilities/7-zip_portable
          • Partager sur Facebook
          • Partager sur Twitter
            26 octobre 2018 à 22:07:27

            Et pourquoi pas? Le produit sur lequel je bosse impose un SGBD, on s'est débrouillé pour que le client ait le choix entre plusieurs SGBD, mais il doit en choisir un parmi la liste qu'on lui propose, ou bien faire un très gros chèque pour qu'on lui développe l'interface avec le SGBD de ses rêves...

            L'installation d'un truc comme 7z n'est pas une grosse contrainte, c'est nettement moins lourd, qu'un runtime SQLServer, Oracle ou autre...

            • Partager sur Facebook
            • Partager sur Twitter
            Mettre à jour le MinGW Gcc sur Code::Blocks. Du code qui n'existe pas ne contient pas de bug
              27 octobre 2018 à 0:37:13

              Zérotisme a écrit:

              Et pourquoi ne pas installer 7z sur ta machine et l'appeler par ligne de commande ?


              Ouais, heu …. ouvrir un shell additionel, bof ….

              @Maluna: As-tu contacté les éditeurs ?

              • Partager sur Facebook
              • Partager sur Twitter
                27 octobre 2018 à 11:56:23

                @Deedolith, pourquoi ouvrir un shell additionnel? Depuis quand, doit on ouvrir un shell pour exécuter un processus  externe en lui passant une ligne de commande? Je suis certainement capable de gérer de la compression, mais 7z le fait probablement bien mieux que moi, donc question. Est ce que je me fais chier à faire ma propre compression, ou est ce que je fais appel à 7z? Ma réponse à moi, c'est que j'ai autre chose à faire que de m’occuper de compression, donc 7z se charge de ce détail, c'est parfait ^^

                -
                Edité par int21h 27 octobre 2018 à 12:00:57

                • Partager sur Facebook
                • Partager sur Twitter
                Mettre à jour le MinGW Gcc sur Code::Blocks. Du code qui n'existe pas ne contient pas de bug
                  27 octobre 2018 à 12:54:45

                  Et à priori c'est plus simple que d'utiliser d'autres librairies ? Je pense notamment à QuaZIP.
                  • Partager sur Facebook
                  • Partager sur Twitter
                    27 octobre 2018 à 14:38:34

                    Tu auras du mal à faire plus simple que ça 

                    fs::path extractArchive(fs::path const & archive)
                    {
                        /// L'assert:  archive est un fichier valide et connu comme une archive (zip,arj,7z ...)
                        assert(fs::exists(archive) && isArchive(archive));
                        /// on va chercher le chemin de 7z
                        auto settings = appIniFile();
                        auto unpacker = fs::path{settings->value("import/unpacker").toString().toStdWString()};
                        if (!fs::exists(unpacker)){
                            throw std::runtime_error{"7z.exe not found!"};
                        }
                        /// le répertoire de décompactage
                        auto tempDir = locateApplicationPath(QApplication::applicationDisplayName().toStdWString()) / L"temp";
                        fs::create_directories(tempDir);
                        /// On fait un sous-répertoire spécialement pour l'archive à traiter...
                        tempDir /= getFileName(archive);
                        /// On prépare la ligne de commande
                        auto args = QStringList{} << "x" << "-aoa" << dbpfString(archive) <<
                                                     QString{"-o%1"}.arg(dbpfString(tempDir));
                        /// C'est parti...
                        QProcess process{};
                        process.start(dbpfString(unpacker),args);
                        if (process.waitForFinished(-1)){
                            return tempDir;
                        } 
                        throw std::runtime_error{QString{"extract process finished whith status %1 "}.arg(process.exitCode()).toStdString()};
                    }
                    dbpfString est une fonction qui transforme un fs::path, std::string, std::wstring en QString. Là j'utilise Qt parce que le reste du programme utilise Qt, mais le code ne sera pas franchement différent avec un CreateProcess de l'API Win32. fs::path est un alias, qui en fonction du compilateur, est std::path ou boost::filesystem::path.
                    • Partager sur Facebook
                    • Partager sur Twitter
                    Mettre à jour le MinGW Gcc sur Code::Blocks. Du code qui n'existe pas ne contient pas de bug
                      27 octobre 2018 à 22:13:35

                      Maluna34 a écrit:

                      Bref, j'imagine qu'être sur Windows n'aide pas trop;)

                      Qu'est ce que ça veut dire cette remarque ?

                      Zipper/dezipper avec la zlib, ça se fait bien. Je l'ai fait ... sous Windows justement... (mais avec un code portable), mais c'est du code que j'ai fait pour ma boîte, donc je ne peux pas le faire ici. 

                      • Partager sur Facebook
                      • Partager sur Twitter

                      Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

                        28 octobre 2018 à 10:01:12

                        Je voulais simplement dire que certaines libs ne prennent pas en compte Windows dans leurs instructions ou ne sont pas testées dessus tout simplement. ^^

                        C'est pour ma boite aussi que je dois faire ça. A voir si ça se fat bien avec zlib, en effet. :)

                        • Partager sur Facebook
                        • Partager sur Twitter
                          28 octobre 2018 à 20:59:19

                          zlib permet de décompresser des blocs zippés, voir de décompresser le format Gzip, qui est assez simple : un petit header de quelques octets et ensuite un bloc zippé.

                          Après, si vraiment tu veux faire un fichier zip, il y a une gestion de l'arborescence avec. Mais en soit, c'est pas bien méchant à faire :

                          Voici le format ZIP :

                          https://en.wikipedia.org/wiki/Zip_(file_format)


                          Comme tu vois, des petits blocs avec le nom de fichier, des tailles, et ensuite des blocs "zippés" pour chaque fichier. (ce que fait minizip mais qui peut se faire à la main si tu veux)


                          Tout dépend ce que tu veux faire. Si tu veux absolument faire des fichiers ZIP (que ton client pourra ouvrir avec winzip), voit avec gzip (zlib) si tu n'as qu'un seul fichier a mettre, ou alors minizip si tu veux en mettre plusieurs.


                          Si ton seul but est de faire un fichier compact sur le disque que seul ton programme peut relire, fait toi un gzip, ou même directement un bloc zippé (deflate) avec zlib.

                          -
                          Edité par Fvirtman 28 octobre 2018 à 21:01:09

                          • Partager sur Facebook
                          • Partager sur Twitter

                          Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

                            28 octobre 2018 à 21:49:51

                            Ok merci de la piste. :) En fait dans mon cas comme j'avais précisé, c'est pour modifier des valeurs dans un xlsx.
                            • Partager sur Facebook
                            • Partager sur Twitter
                              28 octobre 2018 à 22:16:08

                              Est ce que tu ne peux pas passer par un fichier CSV ? (fichier pour tableur simplissime, que excel reconnait)
                              • Partager sur Facebook
                              • Partager sur Twitter

                              Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

                                29 octobre 2018 à 11:07:03

                                Maluna34 a écrit:

                                Ok merci de la piste. :) En fait dans mon cas comme j'avais précisé, c'est pour modifier des valeurs dans un xlsx.



                                Il vaut peut-être mieux utiliser une librairie pour manipuler excel, plutôt que renommer le fichier en zip et manipuler de façon hasardeuse les XML ?
                                Il peut y avoir plein de dépendances la dedans.
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  29 octobre 2018 à 14:41:14

                                  Je suis à 100% d'accord avec @Deedolith, aussi bien pour le manque quasi-total de contrôle lors de l'exécution dans un processus externe, que de l'utilisation de librairies dédiées à ce type de tâche.

                                  Pour le .xlsx, sauf erreur de ma part, il est tout à fait possible d'avoir une source de données externe au fichier, un fichier CSV, via "file" ou "http", REST etc..., et autres formats "conventionnels" de transfert de données.

                                  Il est donc assez simple de modifier ces sources de données plutôt que le fichier .xlsx lui-même.

                                  Si le fait d'avoir les données "fourrées" dans le fichier .xlsx est un "pré-requis", genre tradition de la dinde de Thanksgiving, il existe tout un SDK .NET pour manipuler des fichiers au format OOXML, c'est du .NET donc utilisable en C++/CLI :

                                  https://docs.microsoft.com/en-us/office/open-xml/open-xml-sdk

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                  Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                                    29 octobre 2018 à 19:30:51

                                    @Fvirtman

                                    Non c'est absolument un xlsx qui possède des images et compagnie.

                                    @Deedolith

                                    C'était la piste initiale mais c'était au niveau des licences que ça coinçait. Procédures de la boite. Mais pour info en allant toucher les valeurs dans les xml ça marche. ;)

                                    J'avais réussi à avoir un résultat avec QuaZip. Mais finalement ça va se faire via QaxObject pour éviter d'ajouter des dépendances, contraintes de la boite. Merci à tous ! :)

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      29 octobre 2018 à 20:16:23

                                      >mais c'était au niveau des licences que ça coinçait

                                      Le SDK Open XML est Open Source :

                                      https://github.com/OfficeDev/Open-XML-SDK

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                      Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                                        30 octobre 2018 à 11:01:44

                                        C'était la piste initiale mais c'était au niveau des licences que ça coinçait. Procédures de la boite. Mais pour info en allant toucher les valeurs dans les xml ça marche.

                                        Oui, dans des cas particulier, ou dans le monde des bisounours, ça marche.
                                        Par expérience, on finis toujours par rencontrer, tôt ou tard, le cas qui merdoie.

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          30 octobre 2018 à 11:33:03

                                          >tôt ou tard, le cas qui merdoie.

                                          Encore plus quand on s'est paluché la norme de plus de 5000 pages et qu'elle est truffée d'erreurs et d'imprécisions.

                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                          Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                                            1 novembre 2018 à 23:29:26

                                            Ma méthode permet de s'éviter de se palucher les 500 pages de norme pour des nefles, 7z.exe fait le boulot, la belle affaire, j'appelle 7z pour faire le boulot. C'est exactement la même chose que Sql Server ou Oracle ou n'importe quel SGBD fait le boulot, je ne vais pas me palucher mon propre SGBD alors que j'en ai plein sur le marché qui font le boulot bien mieux que je ne pourrais jamais le faire... Et ça s'applique à tout ou presque, pour la crypto, j'ai des libs de crypto qui vont bien, je veux de la 3d, c'est pas le choix qui manque... Quelque part je suis un grand enfant qui joue au légo, mon boulot en tant que développeur professionnel, c'est souvent de mixer tout ça pour en faire un truc utilisable par le commun des mortels.

                                            -
                                            Edité par int21h 1 novembre 2018 à 23:51:40

                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                            Mettre à jour le MinGW Gcc sur Code::Blocks. Du code qui n'existe pas ne contient pas de bug

                                            Lib Zip / Unzip en mémoire

                                            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                            • Editeur
                                            • Markdown