52 votes

Comment compresser/décompresser des fichiers tar.gz en java

Quelqu'un peut-il m'indiquer la manière correcte de compresser et de décompresser des fichiers tar.gzip en java ? J'ai cherché mais tout ce que j'ai pu trouver, c'est zip ou gzip (seul).

4 votes

Les fichiers tgz n'ont rien de spécial : il faut d'abord les dézipper, puis les dé-tarer.

0 votes

0 votes

42voto

thrau Points 478

J'ai écrit une enveloppe pour commons-compress llamado jarchivelib qui permet d'extraire ou de compresser facilement de et vers File objets.

Un exemple de code ressemblerait à ceci :

File archive = new File("/home/thrau/archive.tar.gz");
File destination = new File("/home/thrau/archive/");

Archiver archiver = ArchiverFactory.createArchiver("tar", "gz");
archiver.extract(archive, destination);

1 votes

C'est génial - cela fonctionne de la même manière qu'un utilitaire de ligne de commande - dézipper <archive> <destination>, en faisant abstraction de tous les détails de la plaque de plomberie (peut-être que si je devais m'inquiéter des performances, j'utiliserais la bibliothèque commons-compress, mais je n'en ai presque jamais besoin).

0 votes

@thrau : Cela me donne une erreur de compilation comme : La méthode createArchiver(String, String) est indéfinie pour le type String.

0 votes

Et ajoutez la distribution à l'archiveur

33voto

Petr Kozelka Points 2515

Mon favori est plexus-archiver - voir les sources sur GitHub .

Une autre option est Apache commons-compress - (voir mvnrepository ).

Avec plexus-utils, le code pour désarchiver ressemble à ceci :

final TarGZipUnArchiver ua = new TarGZipUnArchiver();
// Logging - as @Akom noted, logging is mandatory in newer versions, so you can use a code like this to configure it:
ConsoleLoggerManager manager = new ConsoleLoggerManager();
manager.initialize();
ua.enableLogging(manager.getLoggerForComponent("bla"));
// -- end of logging part
ua.setSourceFile(sourceFile);
destDir.mkdirs();
ua.setDestDirectory(destDir);
ua.extract();

Les classes *Archiver similaires sont là pour l'archivage.

Avec Maven, vous pouvez utiliser ceci dépendance :

<dependency>
  <groupId>org.codehaus.plexus</groupId>
  <artifactId>plexus-archiver</artifactId>
  <version>2.2</version>
</dependency>

17voto

RemusS Points 509

Pour extraire le contenu du format .tar.gz, j'utilise avec succès apache commons-compress ('org.apache.commons:commons-compress:1.12'). Jetez un coup d'œil à cet exemple de méthode :

public void extractTarGZ(InputStream in) {
    GzipCompressorInputStream gzipIn = new GzipCompressorInputStream(in);
    try (TarArchiveInputStream tarIn = new TarArchiveInputStream(gzipIn)) {
        TarArchiveEntry entry;

        while ((entry = (TarArchiveEntry) tarIn.getNextEntry()) != null) {
            /** If the entry is a directory, create the directory. **/
            if (entry.isDirectory()) {
                File f = new File(entry.getName());
                boolean created = f.mkdir();
                if (!created) {
                    System.out.printf("Unable to create directory '%s', during extraction of archive contents.\n",
                            f.getAbsolutePath());
                }
            } else {
                int count;
                byte data[] = new byte[BUFFER_SIZE];
                FileOutputStream fos = new FileOutputStream(entry.getName(), false);
                try (BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER_SIZE)) {
                    while ((count = tarIn.read(data, 0, BUFFER_SIZE)) != -1) {
                        dest.write(data, 0, count);
                    }
                }
            }
        }

        System.out.println("Untar completed successfully!");
    }
}

1 votes

Puisque vous utilisez la syntaxe try-with-resources, vous ne devriez pas avoir besoin de dest.close(); y tarIn.close();

1 votes

Attention : Ceci n'est pas sûr à cause de ZipSlip, n'utilisez pas ce code dans un logiciel de production. En particulier, f.mkdir() n'est pas sûr à appeler en aveugle : snyk.io/research/zip-slip-vulnerability (en anglais)

7voto

Gili Points 14674

D'après mon expérience Apache Compress est beaucoup plus mature que Archivage de Plexus notamment en raison de problèmes tels que http://jira.codehaus.org/browse/PLXCOMP-131 .

Je crois qu'Apache Compress est également plus actif.

0 votes

Apache Compress ne peut pas extraire certaines archives tar.gz en raison d'un manque de support. Ce bogue n'a jamais été résolu : jfrog.com/jira/browse/HAP-651

4 votes

@didile comment voulez-vous que cela soit corrigé si le bogue a été signalé à jfrog au lieu d'apache compress ?

0 votes

Le problème a également été signalé au gestionnaire de problèmes d'Apache.

2voto

Dherik Points 115

Si vous envisagez de compresser/décompresser sur Linux vous pouvez appeler la ligne de commande du shell pour le faire à votre place :

Files.createDirectories(Paths.get(target));
ProcessBuilder builder = new ProcessBuilder();
builder.command("sh", "-c", String.format("tar xfz %s -C %s", tarGzPathLocation, target));
builder.directory(new File("/tmp"));
Process process = builder.start();
int exitCode = process.waitFor();
assert exitCode == 0;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X