Zip récursif

Résolu
bmouget Messages postés 43 Date d'inscription lundi 31 mars 2003 Statut Membre Dernière intervention 4 mars 2011 - 9 sept. 2008 à 15:40
cs_Bidou Messages postés 5486 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 - 20 nov. 2008 à 12:13
Bonjour,

J'utilise SharpZip pour compresser un répertoire dans un fichier Zip.
Les fichiers du dossier sont bien compressés mais je voudrais compresser également tous les dossiers et fichiers récursifs.

Une idée ?

Merci.

Code :

        public static void Zip(string FolderName, string ZipFileName)
        {
            try
            {
                // Depending on the directory this could be very large and would require more attention
                // in a commercial package.
                string[] filenames = Directory.GetFiles(FolderName);


                // 'using' statements gaurantee the stream is closed properly which is a big source
                // of problems otherwise.  Its exception safe as well which is great.
                using (ZipOutputStream s = new ZipOutputStream(File.Create(ZipFileName)))
                {


                    s.SetLevel(6); // 0 - store only to 9 - means best compression


                    byte[] buffer = new byte[4096];


                    foreach (string file in filenames)
                    {


                        // Using GetFileName makes the result compatible with XP
                        // as the resulting path is not absolute.
                        ZipEntry entry = new ZipEntry(Path.GetFileName(file));


                        // Setup the entry data as required.


                        // Crc and size are handled by the library for seakable streams
                        // so no need to do them here.


                        // Could also use the last write time or similar for the file.
                        entry.DateTime = DateTime.Now;
                        s.PutNextEntry(entry);


                        using (FileStream fs = File.OpenRead(file))
                        {


                            // Using a fixed size buffer here makes no noticeable difference for output
                            // but keeps a lid on memory usage.
                            int sourceBytes;
                            do
                            {
                                sourceBytes = fs.Read(buffer, 0, buffer.Length);
                                s.Write(buffer, 0, sourceBytes);
                            } while (sourceBytes > 0);
                        }
                    }




                    // Finish/Close arent needed strictly as the using statement does this automatically


                    // Finish is important to ensure trailing information for a Zip file is appended.  Without this
                    // the created file would be invalid.
                    s.Finish();


                    // Close is important to wrap things up and unlock the file.
                    s.Close();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception during processing {0}", ex);


                // No need to rethrow the exception as for our purposes its handled.
            }
        }

8 réponses

bmouget Messages postés 43 Date d'inscription lundi 31 mars 2003 Statut Membre Dernière intervention 4 mars 2011
9 sept. 2008 à 16:07
Ok c'est bon j'ai trouvé, c'est tout bête.

Pour ceux à qui cela intéresse, voici le code :

        public static void Zip(string FolderName, string ZipFileName)
        {
            try
            {


                // 'using' statements gaurantee the stream is closed properly which is a big source
                // of problems otherwise.  Its exception safe as well which is great.
                using (ZipOutputStream s = new ZipOutputStream(File.Create(ZipFileName)))
                {
                    s.SetLevel(6); // 0 - store only to 9 - means best compression


                    ZipRecusive(s, FolderName, "");


                    s.Finish();


                    s.Close();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception during processing {0}", ex);


                // No need to rethrow the exception as for our purposes its handled.
            }
        }


        private static void ZipRecusive(ZipOutputStream s, string FolderName, string RecursivePath)
        {
            // 1 Fichier
            string[] filenames = Directory.GetFiles(FolderName + RecursivePath);
            foreach (string file in filenames)
            {
                ZipEntry entry = new ZipEntry(RecursivePath + Path.GetFileName(file));


                // Could also use the last write time or similar for the file.
                entry.DateTime = DateTime.Now;
                s.PutNextEntry(entry);


                using (FileStream fs = File.OpenRead(file))
                {
                    byte[] buffer = new byte[4096];
                    // Using a fixed size buffer here makes no noticeable difference for output
                    // but keeps a lid on memory usage.
                    int sourceBytes;
                    do
                    {
                        sourceBytes = fs.Read(buffer, 0, buffer.Length);
                        s.Write(buffer, 0, sourceBytes);
                    } while (sourceBytes > 0);
                }
            }


            // 2 Répertoires
            string[] directorynames = Directory.GetDirectories(FolderName + RecursivePath);
            foreach (string directory in directorynames)
            {
                ZipRecusive(s, FolderName, directory.Substring(FolderName.Length)+@"");
            }
        }
3
cs_Bidou Messages postés 5486 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
14 sept. 2008 à 10:27
Bonjour,
Je ne connais pas bien cette librairie mais le framework possède aussi des possibilités de compressions dans System.IO.Compression.

C'est parfois mieux que de rajouter une nouvelle dépendance sur une librairie externe...
0
bmouget Messages postés 43 Date d'inscription lundi 31 mars 2003 Statut Membre Dernière intervention 4 mars 2011
15 sept. 2008 à 09:11
Bonjour,

As-tu un exemple de code utilisant System.IO.Compression à me proposer ?

Merci.
0
cs_Bidou Messages postés 5486 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
15 sept. 2008 à 09:40
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
bmouget Messages postés 43 Date d'inscription lundi 31 mars 2003 Statut Membre Dernière intervention 4 mars 2011
15 sept. 2008 à 10:14
Pas mal, mais j'avais déjà vu que l'on ne pouvait compressé qu'un seul fichier pour une archive zip.
As-tu une idée de comment ajouter un répertoire complet (fichier, sous-répertoire, ...) à l'archive ?
Ton 3éme lien est bien mais je suis obligé de rajouter aussi une dépendance externe.

Merci.
0
maloups Messages postés 12 Date d'inscription dimanche 15 octobre 2006 Statut Membre Dernière intervention 10 janvier 2009
20 nov. 2008 à 11:14
Bonjour à tous !

J'ai egalement du passer par la problèmatique de Zipper un repertoire en Java ainsi que tous ces sous répertoires.
M. Google m'a très rapidement redirigé vers codeSource

J'avoue que le principe de cet algo m'a bien aidé, mais avait kan meme deux gros inconvénient !
- L'utilisation de librairie spécifique alors que les lib java de base font aussi bien
- Ce bout de code ne fonctionne qu'à partir de Java 1.5 (et oui, y'en a qui travail encore avec de plus vieille version de java )

Voici la version remasterisé, qui fonctionne avec Java 1.4 (pas testé avec les versions antérieur), et qui ne nécéssite aucune librairie complémentaire !

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class testZipRecursif {
    static final int BUFFER = 2048;
    
    /**
     * Zip un répertoire en modifiant le niveau de compression
     * @param args
     */
    public static void main(String[] args) {
        //Declaration du repertoire à zipper (linux version)
        //String REP_A_ZIPPER = "//var//testZip//AZipper//";
        //Declaration du repertoire à zipper (windows version)
        String REP_A_ZIPPER = "\\var\\testZip\\AZipper\";

         //Declaration du fichier final (linux version)
        //String ZIP_FILE = "//var//testZip//myfigsLevel.zip";
        //Declaration du fichier final (windows version)
        String ZIP_FILE = "\\var\\testZip\\myfigsLevel.zip";
        
        //Declaration du niveau de compression
        int zipLevel = 0;
        
        //Zip recursif d'un repertoire
        zipRepertoire(REP_A_ZIPPER, ZIP_FILE, zipLevel);
    }

    
    /**
     * Zip recursivement le contenu d'un repertoire
     * @param REP_A_ZIPPER Le repertoire en entree
     * @param ZIP_FILE Le fichier de sortie
     * @param zipLevel Le niveau de compression
     */
    private static void zipRepertoire(String REP_A_ZIPPER, String ZIP_FILE, int zipLevel){
        try {
            //Creation du fichier final
            FileOutputStream dest = new 
              FileOutputStream(ZIP_FILE);
            ZipOutputStream out = new ZipOutputStream(new 
              BufferedOutputStream(dest));
            
            //On definit le niveau de compression
            out.setLevel(zipLevel);
            
            //On zip recursivement le contenu d'un repertoire
            //Ainsi que de ses sous repertoires
            ZipRecusive(out, REP_A_ZIPPER, "");
            
            out.close();
         } catch(IOException e) {
            e.printStackTrace();
         }
    }
    
    /**
     * Permet de traiter recursivement le contenu d'un repertoire
     * @param out Le flux zip de sortie
     * @param REP_A_ZIPPER Le repertoire de base à zipper
     * @param RecursivePath Le sous repertoire que l'on traite
     */
    private static void ZipRecusive(ZipOutputStream out, String REP_A_ZIPPER, String RecursivePath){
        byte data[] = new byte[BUFFER];
        //Creatin de la liste des fichiers present dans un repertoire
        File f = new File(REP_A_ZIPPER+RecursivePath);
        String files[] = f.list();
        BufferedInputStream origin = null;
        ArrayList listDirectory = new ArrayList();
        try{
            //On parcourt la liste des fichiers du repertoire
            for (int i=0; i<files.length; i++) {
                //On recupere le nom du fichier
                String fileName = files[i];
                //On reconstruit le chemin complet du fichier
                String pathAndFile = REP_A_ZIPPER+RecursivePath+fileName;
                //On cherche a savoir si il s'agit un repertoir ou d'un fichier
                File fileTmp = new File(pathAndFile);
                //Si il s'agit d'un repertoire, 
                //on l'ajoute dans une liste de repertoire à traiter
                if (fileTmp.isDirectory()){
                    listDirectory.add(fileName);
                } else {
                   //Traitement du fichier courant
                   FileInputStream fi = new 
                     FileInputStream(pathAndFile);
                   origin = new 
                     BufferedInputStream(fi, BUFFER);
                   //Debut du zipage du fichier courant
                   ZipEntry entry = new ZipEntry(RecursivePath+fileName);
                   out.putNextEntry(entry);
                   int count;
                   while((count = origin.read(data, 0, 
                     BUFFER)) != -1) {
                      out.write(data, 0, count);
                   }
                   origin.close();
                }
            }
            
            //Parcours de la liste des répertoires present dans le repertoire courant
            String[] directoriesName = convertArrayListToStringTab(listDirectory);
            for (int i=0; i<directoriesName.length; i++) {
                String directory = directoriesName[i];
                ZipRecusive(out, REP_A_ZIPPER, directory+"\");
            }
         } catch(IOException e) {
            e.printStackTrace();
         }
    }
    
    /**
     * Convertir un ArrayList en String[]
     * @return un tableau de chaine de caractère
     */
    private static String[] convertArrayListToStringTab(ArrayList list){
        String[] res = new String[list.size()];
        
        for (int i=0; i<list.size(); i++){
            res[i] = list.get(i).toString();
        }
        
        return res;
    }
}



Voili voilou !
0
maloups Messages postés 12 Date d'inscription dimanche 15 octobre 2006 Statut Membre Dernière intervention 10 janvier 2009
20 nov. 2008 à 11:19
Lol, j'ai pas trouvé comment modifier mon poste... un peu a la rue moi
Pas vu qu'on etait dans un section CSharp... faut avouer que ca ressemble beaucoup à du java
En tout, cas, etant donnée les similitudes, je pense qu'il y aura toujours moy de s'y retrouver
0
cs_Bidou Messages postés 5486 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
20 nov. 2008 à 12:13
Bonjour,
Merci de poser la question sur www.javafr.com.

Meme login et mot de passe.

<hr />
-Blog-
-Site Perso-
0
Rejoignez-nous