IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

API standards et tierces Java Discussion :

compression et décompression d'un tar.gz par programmation java


Sujet :

API standards et tierces Java

  1. #1
    Nouveau membre du Club
    Inscrit en
    Septembre 2006
    Messages
    110
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 110
    Points : 39
    Points
    39
    Par défaut compression et décompression d'un tar.gz par programmation java
    Bonjour,

    Je galère à faire, non pas un programme qui marche, mais un programme "universel" qui sait manger n'importe quel fichier .tar.gz (réaliser par n'importe quel source) pour donner les fichiers finaux en sortie.
    Un fichier .tar.gz doit pouvoir être décompressé quel que soit la source : en particulier il doit être compatible avec des archives créées par :
    - linux
    - 7-zip
    - Programme java (compression)

    Je suis arrivé à faire un programme qui marche, mais que pour certaines sources d'entrée (pas les 3 citées ci-dessus), pourriez-vous me donner un coup de main pour avoir un programme universel ?

    Merci

    NB : j'utilise commons compress comme lib.
    Voici des exemples qui marchent (mais pas universel pour mon cas, seulement les archives faites sous linux marchent) :


    // Récupération du .tar dans l'archive .tar.gz initiale
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     private static File tarGzip2Tar(String archivePath, String archiveBaseName) throws IOException
        {
            InputStream is = new FileInputStream(new File(archivePath, archiveBaseName));
            File tarFile = null;
            BufferedInputStream bfs = new BufferedInputStream(is);
            tarFile = new File(archivePath, FilenameUtils.removeExtension(archiveBaseName));
            FileOutputStream out = new FileOutputStream(tarFile);
            org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream gzIn = new org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream(bfs);
            final byte[] buffer = new byte[1024];
            int n = 0;
            while (-1 != (n = gzIn.read(buffer)))
            {
                out.write(buffer, 0, n);
            }
            out.close();
            gzIn.close();
     
            return tarFile;
        }

    //récupération des fichiers dans le tar
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    private static List<File> uncompressTarGZ(File tarFile, File dest) throws IOException
        {
            dest.mkdir();
            TarArchiveInputStream tarIn = null;
            List<File> extractedFiles = new ArrayList<File>();
     
            tarIn = new TarArchiveInputStream(
                            new GzipCompressorInputStream(
                                            new BufferedInputStream(
                                                            new FileInputStream(
                                                                            tarFile
                                                            )
                                            )
                            )
                            );
     
            TarArchiveEntry tarEntry = tarIn.getNextTarEntry();
            // tarIn is a TarArchiveInputStream
            while (tarEntry != null)
            {// create a file with the same name as the tarEntry
                File destPath = new File(dest, tarEntry.getName());
                System.out.println("working: " + destPath.getCanonicalPath());
                if (tarEntry.isDirectory())
                {
                    destPath.mkdirs();
                }
                else
                {
                    destPath.createNewFile();
                    //byte [] btoRead = new byte[(int)tarEntry.getSize()];
                    byte[] btoRead = new byte[1024];
                    //FileInputStream fin 
                    //  = new FileInputStream(destPath.getCanonicalPath());
                    BufferedOutputStream bout =
                                    new BufferedOutputStream(new FileOutputStream(destPath));
                    int len = 0;
     
                    while ((len = tarIn.read(btoRead)) != -1)
                    {
                        bout.write(btoRead, 0, len);
                    }
     
                    extractedFiles.add(destPath);
                    bout.close();
                    btoRead = null;
     
                }
                tarEntry = tarIn.getNextTarEntry();
            }
            tarIn.close();
     
            return extractedFiles;
        }
    //et le programme de compression

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    /**
         * Compress (tar.gz) the input files to the output file
         *
         * @param files The files to compress
         * @param output The resulting output file (should end in .tar.gz)
         * @throws IOException
         */
        public static File compressFilesInTarGz(Collection<File> files, String absoluteDestDirname, String outputTarGzFilename)
                        throws IOException
        {
            String absoluteOutputTarGzFilename = absoluteDestDirname + File.separator + outputTarGzFilename;
            if (log.isDebugEnabled())
            {
                log.debug("Compressing " + files.size() + " to " + absoluteOutputTarGzFilename + ": " + files);
            }
            new File(absoluteDestDirname).mkdirs();
            File outputTarGzFile = new File(absoluteOutputTarGzFilename);
            outputTarGzFile.createNewFile();
            // Create the output stream for the output file
            FileOutputStream fos = new FileOutputStream(outputTarGzFile);
            // Wrap the output file stream in streams that will tar and gzip everything
            TarArchiveOutputStream taos = new TarArchiveOutputStream(
                            new GZIPOutputStream(new BufferedOutputStream(fos)));
            // TAR originally didn't support long file names, so enable the support for it
            taos.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
     
            // Get to putting all the files in the compressed output file
            int extensionSeparatorIndex = outputTarGzFile.getName().indexOf(FilenameUtils.EXTENSION_SEPARATOR_STR);
            String baseFilenameWithoutExtension = outputTarGzFile.getName();
            if (extensionSeparatorIndex > 0)
            {
                baseFilenameWithoutExtension = StringUtils.substring(outputTarGzFilename, 0, extensionSeparatorIndex);
            }
            for (File f : files)
            {
                addFilesToCompression(taos, f, baseFilenameWithoutExtension);
            }
     
            // Close everything up
            taos.close();
            fos.close();
     
            return outputTarGzFile;
        }
     
        /**
         * Does the work of compression and going recursive for nested directories
         * <p/>
         *
         * Borrowed heavily from http://www.thoughtspark.org/node/53
         *
         * @param taos The archive
         * @param file The file to add to the archive
             * @param dir The directory that should serve as the parent directory in the archivew
         * @throws IOException
         */
        private static void addFilesToCompression(TarArchiveOutputStream taos, File file, String dir)
                        throws IOException
        {
            // Create an entry for the file
            taos.putArchiveEntry(new TarArchiveEntry(file, file.getName()));
            if (file.isFile())
            {
                // Add the file to the archive
                BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
                IOUtils.copy(bis, taos);
                taos.closeArchiveEntry();
                bis.close();
            }
            else if (file.isDirectory())
            {
                // close the archive entry
                taos.closeArchiveEntry();
                // go through all the files in the directory and using recursion, add them to the archive
                for (File childFile : file.listFiles())
                {
                    addFilesToCompression(taos, childFile, file.getName());
                }
            }
        }

  2. #2
    Modérateur
    Avatar de wax78
    Homme Profil pro
    Chef programmeur
    Inscrit en
    Août 2006
    Messages
    4 075
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chef programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 4 075
    Points : 7 981
    Points
    7 981
    Par défaut
    Bah, TAR.GZ est un format universel, peut importe avec quel programme il a été crée en théorie.

    Dans quels cas ca ne fonctionne pas ? (la liste des couples, compression/decompression ainsi que le programme qui extrait ou compresse avec le resultat positif ou non).
    (Les "ça ne marche pas", même écrits sans faute(s), vous porteront discrédit ad vitam æternam et malheur pendant 7 ans)

    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Nouveau membre du Club
    Inscrit en
    Septembre 2006
    Messages
    110
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 110
    Points : 39
    Points
    39
    Par défaut
    C'est bon, j'ai travaillé toute cet aprem sur cette m****.
    Le "cheat code" apparaît dans la méthode "doUnTar()" ci-dessous.
    Quelque que soit la source de compression en tar.gz, je "dé-Gzip" facilement.
    Par contre ensuite, je dois "dé-taré" et là il y a une variante.
    Si l'archive a été crée sous un unix, la méthode isGzipStream renvoie true.
    Si l'archive a été crée par mon programme de compression en .tar.gz ou bien par 7-zip, isGzipStream renvoie false.
    Du coup, avec le if/else, la méthode doUntar() marche dans tous les cas et ainsi je peux récupérer les fichiers finaux.

    CQFD



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    private static List<File> doUnTar(File unGzipFile, String destDirname) throws IOException
        {
            List<File> files = new ArrayList<File>();
     
     
            new File(destDirname).mkdir();
            FileInputStream is = new FileInputStream(unGzipFile);
            TarArchiveInputStream tarIn = null;
            if (isGzipStream(FileUtils.readFileToByteArray(unGzipFile)))
            {
                tarIn =
                                new TarArchiveInputStream(
                                                new GzipCompressorInputStream(
                                                                new BufferedInputStream(
                                                                                is
                                                                )
                                                )
                                );
            }
            else
            {
                tarIn =
                                new TarArchiveInputStream(
                                                new BufferedInputStream(
                                                                is
                                                )
                                );
            }
     
     
            //                        new TarArchiveInputStream(
            //                        is);
            TarArchiveEntry tarEntry = tarIn.getNextTarEntry();
            // tarIn is a TarArchiveInputStream
            while (tarEntry != null)
            {// create a file with the same name as the tarEntry
                File destPath = new File(destDirname, tarEntry.getName());
                System.out.println("working: " + destPath.getCanonicalPath());
                if (tarEntry.isDirectory())
                {
                    destPath.mkdirs();
                }
                else
                {
                    destPath.createNewFile();
                    FileOutputStream fout = new FileOutputStream(destPath);
                    tarIn.read(new byte[(int) tarEntry.getSize()]);
                    fout.close();
                    files.add(destPath);
                }
                tarEntry = tarIn.getNextTarEntry();
            }
            tarIn.close();
     
            return files;
        }
     
     public static boolean isGzipStream(byte[] bytes)
        {
            int head = (bytes[0] & 0xff) | ((bytes[1] << 8) & 0xff00);
            return (GZIPInputStream.GZIP_MAGIC == head);
        }

  4. #4
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 552
    Points : 21 608
    Points
    21 608
    Par défaut
    Dude, cela signifie simplement que ces programmes ne gzippent rien du tout, et donc ne produisent pas des .tar.gz mais des .tar tout court.

    Je constate en effet que 7-zip ne propose pas de gérer tar et gz à la fois, il ne le propose qu'en deux étapes... C'est nul -_-°.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

Discussions similaires

  1. Réponses: 0
    Dernier message: 16/05/2011, 09h52
  2. [2.0] Comment compresser et décompresser un string
    Par tooff dans le forum Framework .NET
    Réponses: 3
    Dernier message: 08/04/2010, 16h20
  3. Logiciel pour décompresser un fichier .TAR
    Par Mousk dans le forum Autres Logiciels
    Réponses: 8
    Dernier message: 12/03/2006, 19h52
  4. logiciel pour compresser et décompresser tout les formats
    Par vampyer972 dans le forum Autres Logiciels
    Réponses: 12
    Dernier message: 28/02/2006, 19h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo