#0 

11-02-2010 14:55:37

xapantu
Membre
Date d'inscription: 11-02-2010
Messages: 12

Bonjour tout le monde !
Bon voilà, dans le programme que je développe, j'aurais besoin de décompresser des fichier zip et je crois avoir lu quelques part que on pouvait le faire avec irrlicht.
Le seul problème, c'est que évidemment, quand je cherche "irrlicht zip" sur Google ou sur ce forum, je ne tombe que sur des articles ou des post qui parlent des sorties d'irrlicht : "irrlicht-1.7.zip", etc... A moins que je me trompe et qu'on  ne puisse pas faire ça avec irrlicht ??? oO

Donc je n'arrive pas à trouver les pages de docs, ou des tutoriels, donc si quelqu'un avait quelques liens, ça serait sympa smile

D'avance, merci !

Dernière modification par xapantu (11-02-2010 14:57:58)

Hors ligne


#1 

11-02-2010 15:49:43

Hawk
Membre
Lieu: Wissous
Date d'inscription: 08-11-2008
Messages: 91
Site web

Salut,

Pour ma part, je n'ai pas encore essayé, mais je suis convaincu que c'est effectivement possible.
Je pense qu'il faut creuser du coté de l'interface IArchiveFile, qui permet d'ouvrir et lire le contenu d'archives.
http://irrlicht.sourceforge.net/docu/cl … chive.html
En utilisant "getFileList", tu dois pouvoir récupérer ce qu'il y a dans ton archive, puis avec "createAndOpenFile" choisir un fichier de cette liste pour l'ouvrir. (Enfin je pense que c'est comme ça que ça marche)

J'espère que ceci pourra t'aider, et si tu t'en sors, un petit retour avec un bout de code serait le bienvenue.

Hors ligne


#2 

11-02-2010 16:57:43

xapantu
Membre
Date d'inscription: 11-02-2010
Messages: 12

Merci, je viens de regarder mais je bloque là :
    IFileArchive * zipfile;
    IReadFile* file = zipfile->createAndOpenFile("zip.zip");

(sachant que le fichier zip.zip existe bien)
Il m'affiche une erreur de segmentation.

J'ai du louper un truc évident (c'est la première fois que je fait un vrai truc en c++ ) mais quoi ? Je crois que ça vient de l'argument mais je n'arrive pas à comprendre ce qu'il faut mettre à la place... sad

Dernière modification par xapantu (11-02-2010 17:03:31)

Hors ligne


#3 

11-02-2010 17:27:35

nabouill
Abonné
Date d'inscription: 17-09-2009
Messages: 242
Corrections: 1

J'ai trouvé ça : http://www.example-code.com/vcpp/zip.asp
C'est pas du Irrlicht mais une bonne lib de manupulition de fichier zip.


mes sites: www.manga-vf.fr et www.series-vf.fr

Hors ligne


#4 

11-02-2010 17:29:46

xapantu
Membre
Date d'inscription: 11-02-2010
Messages: 12

En fait ça serait pour un programme sur plusieurs système d'exploitation et j'aimerais limiter les problèmes de dépendances, donc utiliser seulment irrlicht ça serait plus simple smile .

Dernière modification par xapantu (11-02-2010 17:49:10)

Hors ligne


#5 

11-02-2010 17:50:11

Ilovechocolat
Abonné
Date d'inscription: 07-10-2009
Messages: 125

Est-ce-que tes zip ont un mot de pass ?

Hors ligne


#6 

11-02-2010 18:11:23

xapantu
Membre
Date d'inscription: 11-02-2010
Messages: 12

Non, ce sont de simple zip (enfin je vais quand même essayer avec d'autres pour voir) mais je n'arrive pas à comprendre ce que signifie :

Code:

createAndOpenFile  (const path  &filename)

(extrait de la doc d'irrlicht)

et moi j'utilise :

Code:

    IFileArchive * zipfile;
    IReadFile* file = zipfile->createAndOpenFile("zip.zip");

Je pense que le problème vient de là. Quelqu'un à une idée ?

Hors ligne


#7 

11-02-2010 19:15:40

Hawk
Membre
Lieu: Wissous
Date d'inscription: 08-11-2008
Messages: 91
Site web

Ton pointeur sur IFileArchive est null. D'où le SEGFAULT.
Je pense qu'il doit falloir utiliser le File System d'abord pour ajouter des archives (addZipFileArchive) que tu récupère ensuite avec getFileArchive, et ensuite tu pourra récupérer la liste des objets dans ton archive.

Code c++ :


...

//Récupère le FileSystem
IFileSystem*  pfs = device->getFileSystem();
//Ajoute ton archive
pfs->addZipFileArchive("zip.zip"); //Attention au chemin
//Récupère ton archive
IFileArchive * zipfile = pfs->getFileArchive(0);
//Récupère le premier fichier de ton archive
IReadFile* file = zipfile->createAndOpenFile(0);
//Ou Encore
IReadFile* file2 = zipfile->createAndOpenFile("monfichierdanslezip.txt");

Dernière modification par Hawk (11-02-2010 19:16:40)

Hors ligne


#8 

11-02-2010 19:32:08

xapantu
Membre
Date d'inscription: 11-02-2010
Messages: 12

Super, merci beaucoup smile
Je vais essayer de finir ça en décompressant les fichiers, je n'avais pas du tout compris le principe de la classe IFileArchive smile

Hors ligne


#9 

11-02-2010 20:31:23

Ilovechocolat
Abonné
Date d'inscription: 07-10-2009
Messages: 125

T'as essayé comme ça :

Code:

device->getFileSystem()->addZipFileArchive("file.zip");

après normalement tu peut faire ça si ton zip contient un fichier comme  une texture :

Code:

driver->getTexture("texture_contenu_dans_le_zip.bmp")

Évidement ça marche avec tout les types de fichier (pas que les textures).

createAndOpenFile crée un nouveau fichier.

Dernière modification par Ilovechocolat (11-02-2010 20:35:52)

Hors ligne


#10 

11-02-2010 21:07:31

xapantu
Membre
Date d'inscription: 11-02-2010
Messages: 12

Ok, merci smile
Et quelqu'un sait comment on recopie un fichier qui est chargé dans un IReadFile parce que là que ce soit dans l'exemple de Ilovechocolat ou de Hawk, je n'arrive pas à recopier le fichier dans un dossier externe après sad

Merci beaucoup pour tout big_smile !

Dernière modification par xapantu (11-02-2010 21:08:03)

Hors ligne


#11 

12-02-2010 08:58:05

xapantu
Membre
Date d'inscription: 11-02-2010
Messages: 12

Je crois qu'il faut utiliser la méthode read de IReadFile et écrire le contenu dans un IWriteFile avec write mais je ne parviens pas à compre,dre comment marche les buffer (et surtout comment les initialiser), j'ai essayé avec un tableau de char mais ça ne marche pas sad

Quelqu'un a une idée big_smile ?

Et encore merci pour l'aide !

Hors ligne


#12 

12-02-2010 12:27:52

Ilovechocolat
Abonné
Date d'inscription: 07-10-2009
Messages: 125

Les buffer c'est pas les données sur le maillage d'un mesh ? La définition de google c'est "tampon" mais ça m'étonnerais que ce soit ça.
Sino si c'est pour créer un fichier, t'a des fonctions C et des class C++ dans la lib standart pour faire ça.

Dernière modification par Ilovechocolat (12-02-2010 12:43:44)

Hors ligne


#13 

12-02-2010 13:08:16

xapantu
Membre
Date d'inscription: 11-02-2010
Messages: 12

Non, ce n'est pas que de données sur un mesh, par exemple  :

Code:

virtual s32 irr::io::IReadFile::read      (      void *        buffer,
        u32      sizeToRead     
    )

et il y a l'équivalent avec write :

Code:

virtual s32 irr::io::IWriteFile::write      (      const void *        buffer,
        u32      sizeToWrite     
    )

http://irrlicht.sourceforge.net/docu/cl … _file.html
et donc je pense que en écrivant avec write les données récupérés avec read, on doit pouvoir dupliquer un fichier mais je ne sais pas comment utilisant ces buffer sad

Dernière modification par xapantu (12-02-2010 13:08:42)

Hors ligne


#14 

12-02-2010 13:15:32

xapantu
Membre
Date d'inscription: 11-02-2010
Messages: 12

Je viens de trouver ça : http://irrlicht.sourceforge.net/phpBB2/ … iwritefile je vais essayer

Hors ligne


#15 

12-02-2010 13:24:30

xapantu
Membre
Date d'inscription: 11-02-2010
Messages: 12

Bon bah c'est bon ça marche :

Code:

s32 IFileSystem_copyFileToFile(IWriteFile* dst, IReadFile* src)
{
  char buf[1024];
  const s32 sz = sizeof(buf) / sizeof(*buf);

  s32 r, rx = src->getSize();
  for (r = 0; r < rx; /**/)
  {
    s32 w, wx = src->read(buf, sz);
    for (w = 0; w < wx; /**/)
    {
      s32 n = dst->write(buf + w, wx - w);
      if (n < 0)
        return -1;
      else
        w += n;
    }
    r += w;
  }

  return r;
}

dans une fonction :

Code:

IrrlichtDevice * device = irr_driver->getDevice();
IFileSystem*  pfs = device->getFileSystem();
//Ajoute ton archive
pfs->addZipFileArchive("zip.zip"); //Attention au chemin
//Récupère ton archive
IFileArchive * fs = pfs->getFileArchive(0);
IReadFile* srcFile = pfs->createAndOpenFile("fileOnZip");
IWriteFile* dstFile = pfs->createAndWriteFile("fileOnDisk.txt");

if (IFileSystem_copyFileToFile(dstFile, srcFile) < 0)
; // error

srcFile->drop();
dstFile->drop();

Merci à tous wink

Dernière modification par xapantu (12-02-2010 13:25:56)

Hors ligne


#16 

12-02-2010 13:30:47

Hawk
Membre
Lieu: Wissous
Date d'inscription: 08-11-2008
Messages: 91
Site web

Un buffer, c'est un terme très générique qui peut désigner beaucoup de choses. En gros, c'est juste un tableau de données. (version très simplifiée) Tampon, c'est effectivement le nom qu'on donne aux buffers informatiques en français, mais bon, je trouve ça moche, j'appelle ça des buffers.
http://fr.wikipedia.org/wiki/M%C3%A9moire_tampon
CF le dernier paragraphe.

Je pense qu'un truc qui pourrait marcher ce serait :

Code c++ :


//Récupère le FileSystem
IFileSystem*  pfs = device->getFileSystem();
//Ajoute ton archive
pfs->addZipFileArchive("zip.zip"); //Attention au chemin
//Récupère ton archive
IFileArchive * zipfile = pfs->getFileArchive(0);
//Récupère le premier fichier de ton archive
IReadFile* fichierlu = zipfile->createAndOpenFile("monfichierdanslezip.txt");
if (fichierlu)
{
    u32 size = fichierlu->getSize(); //La taille du fichier
    //Création du buffer
    char* buffer = new char[size];
    //Lecture du fichier
    fichierlu->read((void*) buffer, size);
    //On créé le fichier à écrite
    IWriteFile* fichierecrit = pfs->createAndWriteFile("zip.zip");
    if (fichierecrit)
    {
        //Ecriture
        fichierecrit->write((void*) buffer, size);
        //Libération mémoire
        fichierecrit->drop();
    }
    //On libère la mémoire, très important
    delete[] buffer;
    buffer = 0;
    fichierlu->drop();
   
}



Je ne suis pas sûr à 100%, mais je pense que ce code va chercher le fichier "monfichierlu.txt" dans ton archive, et va l'écrire dans le répertoire "chemin", sous le nom "monfichierecrit.txt". Evidemment, tu peux garder le même si tu veux. Après pour faire ça pour tous les fichiers de ton zip, avec une boucle for, et les index des fichiers, ça devrait se faire.

Hors ligne


#17 

12-02-2010 13:44:02

xapantu
Membre
Date d'inscription: 11-02-2010
Messages: 12

D'accord merci smile (mais l'exemple précédent marchait aussi, non big_smile ? ).

Et sinon, pourquoi tu met (void*) devant buffer dans les fonctions ?

Dernière modification par xapantu (12-02-2010 13:45:04)

Hors ligne


#18 

12-02-2010 18:18:58

Hawk
Membre
Lieu: Wissous
Date d'inscription: 08-11-2008
Messages: 91
Site web

En fait, tu as posté ton exemple pendant que j'écrivais le mien, du coup je ne l'ai vu qu'après. En fait, c'est la même chose, mais le tien est peut être un peu plus propre au niveau du copy.

Le (void*) n'est pas nécessaire, mais c'est plus propre, je préfère (vu que la fonction demande en entrée un void* et non un char*). Et je me demande si c'est pas obligatoire sur certains compilateurs...

Hors ligne


#19 

13-02-2010 19:13:40

xapantu
Membre
Date d'inscription: 11-02-2010
Messages: 12

D'accord, merci pour tout smile

Hors ligne


#20 

20-04-2010 03:30:34

narugohan
Abonné
Date d'inscription: 24-03-2009
Messages: 113

Excusez-moi de relevez se topic, mais j'ai réussi à extraire mon fichier .zip, ou plutôt le fichier que je voulais extraire de mon fichier .zip, mais comment faire pour extraire entièrement mon fichier .zip, même si je ne connais pas les fichiers qui sont contenue dans celui-ci
Je vous remercie d'avance pour vos réponse

Hors ligne


#21 

20-04-2010 11:30:10

Hawk
Membre
Lieu: Wissous
Date d'inscription: 08-11-2008
Messages: 91
Site web

Avec une boucle for sur la liste des fichiers.
Tu peux utiliser l'indice du fichier plutôt que son nom si tu ne le connais pas.

Code c++ :


...

//Récupère le FileSystem
IFileSystem*  pfs = device->getFileSystem();
//Ajoute ton archive
pfs->addZipFileArchive("zip.zip"); //Attention au chemin
//Récupère ton archive
IFileArchive * zipfile = pfs->getFileArchive(0);
//Récupère le nombre de fichier
//Je n'ai pas la méthode sous le nez, mais ça doit se trouver
int nb_files = ...
//Boucle for :
for (int i = 0; i < nb_files; i++)
{
    //Récupère le fichier de ton archive
    IReadFile* file = zipfile->createAndOpenFile(i);
    //....
}

Hors ligne


#22 

20-04-2010 22:01:35

narugohan
Abonné
Date d'inscription: 24-03-2009
Messages: 113

ok, je te remercie, j'ai réussi à faire l'extraction comme je veux, mais il y a un problème encore, j'ai un dossier dans mon archive, et quand j'essaye de le crée avec la fonction :
     
       createAndWriteFile (const path &filename, bool append=false)=0

le problème, c'est que sa me crée un fichier portant le nom de se dossier, et cela me met dezippe les autres fichier dans dossier de l'archive alors que je voudrai que sa me crée un dossier à la place d'un fichier, et que sa me place les fichiers copris dans se dossier....Bah dans le dossier xD

Voilà mon code au cas où :

Code c++ :


//Récupère le FileSystem
        IFileSystem*  pfs = device->getFileSystem();
        //Ajoute ton archive
        pfs->addZipFileArchive("zip.zip");
        //Récupère ton archive
        IFileArchive * zipfile = pfs->getFileArchive(0);
        const IFileList *fileList = zipfile->getFileList();
        u32 nbxFile = fileList->getFileCount();
        QMessageBox::information(this, "monfichierdanslezip.txt", "zip.zip" + QString::number(nbxFile) );

        //pfs->drop();
        //zipfile->drop();
        //Boucle for :
        for (int i = 0; i < nbxFile; i++)
        {
            //Récupère le fichier de ton archive
            IReadFile* file = zipfile->createAndOpenFile(i);
            ///--->>><<<---///
            u32 size = file->getSize(); //La taille du fichier
            //Création du buffer
            char* buffer = new char[size];
            //Lecture du fichier
            file->read((void*) buffer, size);
            //On créé le fichier à écrite
            if( fileList->isDirectory(i) )
                QMessageBox::information(this, "monfichierlu.txt", "chemin/monfichierecrit.txt" );
            IWriteFile* fichierecrit = pfs->createAndWriteFile(fileList->getFullFileName(i));
            if (fichierecrit)
            {
                //Ecriture
                fichierecrit->write((void*) buffer, size);
                //Libération mémoire
                fichierecrit->drop();
            }
            //On libère la mémoire, très important
            delete[] buffer;
            buffer = 0;
            file->drop();
            ///--->>><<<---///
        }

Dernière modification par narugohan (20-04-2010 22:02:00)

Hors ligne


#23 

22-04-2010 00:01:41

narugohan
Abonné
Date d'inscription: 24-03-2009
Messages: 113

UP SVP

Hors ligne


#24 

25-04-2010 11:57:54

narugohan
Abonné
Date d'inscription: 24-03-2009
Messages: 113

deuxieme UP... personne ?

Hors ligne


Options Liens officiels Caractéristiques Statistiques Communauté
Corrections
irrlicht
irrklang
irredit
irrxml
xhtml 1.0
css 2.1
Propulsé par FluxBB
Traduit par FluxBB.fr
881 membres
1426 sujets
11116 messages
Dernier membre inscrit: Bidule
14 invités en ligne
Aucun membre connecté
RSS Feed