web-dev-qa-db-fra.com

Comment utiliser LZMA SDK pour compresser/décompresser en Java

http://www.7-Zip.org/sdk.html Ce site fournit un SDK LZMA pour les fichiers compressés/décompressés. Je voudrais tenter le coup, mais je suis perdu.

Quelqu'un a de l'expérience sur ce sujet? Ou un tutoriel? Merci.

16
lamwaiman1988

Réponse courte: ne pas

Le sdk 7Zip est ancien et non maintenu. Il s’agit simplement d’un wrapper JNI autour de la bibliothèque C++. Une implémentation Java pure sur une JVM moderne (1.7+) est aussi rapide que C++ et présente moins de problèmes de dépendance et de portabilité.

Regardez http://tukaani.org/xz/Java.html

XZ est un format de fichier basé sur LZMA2 (une version améliorée de LZMA)

Les gars qui ont inventé le format XZ construisent une implémentation Java pure des algorithmes de compression/extraction d'archive XZ

Le format de fichier XZ est conçu pour stocker un seul fichier. Ainsi, vous devez d'abord compresser/compresser le (s) dossier (s) source dans un fichier non compressé.

Utiliser la bibliothèque Java est aussi simple que cela: 

FileInputStream inFile = new FileInputStream("src.tar");
FileOutputStream outfile = new FileOutputStream("src.tar.xz");

LZMA2Options options = new LZMA2Options();

options.setPreset(7); // play with this number: 6 is default but 7 works better for mid sized archives ( > 8mb)

XZOutputStream out = new XZOutputStream(outfile, options);

byte[] buf = new byte[8192];
int size;
while ((size = inFile.read(buf)) != -1)
   out.write(buf, 0, size);

out.finish();
38
Stefano Fratini

Consultez les fichiers LzmaAlone.Java et LzmaBench.Java dans le dossier Java/SevenZip du fichier Zip à partir du lien que vous avez publié.

4
Eve Freeman

Utilisez J7Zip. C'est un port Java du SDK LZMA. Vous le trouvez ici:

http://sourceforge.net/projects/p7Zip/files/J7Zip/

alternative

Utilisez le lzmajio.jar avec les classes LzmaInputStream et LzmaOutputStream

vous le trouvez sur github:

http://github.com/league/lzmajio/downloads

3
Alcar Sharif

Vous pouvez utiliser this library à la place. Il est "obsolète" mais fonctionne toujours bien.

Dépendance Maven

<dependency>
    <groupId>com.github.jponge</groupId>
    <artifactId>lzma-Java</artifactId>
    <version>1.2</version>
</dependency>

Classe d'utilitaire

import lzma.sdk.lzma.Decoder;
import lzma.streams.LzmaInputStream;
import lzma.streams.LzmaOutputStream;
import org.Apache.commons.compress.utils.IOUtils;

import Java.io.*;
import Java.nio.file.Path;

public class LzmaCompressor
{
    private Path rawFilePath;
    private Path compressedFilePath;

    public LzmaCompressor(Path rawFilePath, Path compressedFilePath)
    {
        this.rawFilePath = rawFilePath;
        this.compressedFilePath = compressedFilePath;
    }

    public void compress() throws IOException
    {
        try (LzmaOutputStream outputStream = new LzmaOutputStream.Builder(
                new BufferedOutputStream(new FileOutputStream(compressedFilePath.toFile())))
                .useMaximalDictionarySize()
                .useMaximalFastBytes()
                .build();
             InputStream inputStream = new BufferedInputStream(new FileInputStream(rawFilePath.toFile())))
        {
            IOUtils.copy(inputStream, outputStream);
        }
    }

    public void decompress() throws IOException
    {
        try (LzmaInputStream inputStream = new LzmaInputStream(
                new BufferedInputStream(new FileInputStream(compressedFilePath.toFile())),
                new Decoder());
             OutputStream outputStream = new BufferedOutputStream(
                     new FileOutputStream(rawFilePath.toFile())))
        {
            IOUtils.copy(inputStream, outputStream);
        }
    }
}

Tout d'abord, vous devez créer un fichier avec un contenu pour commencer à compresser. Vous pouvez utiliser this website pour générer un texte aléatoire.

Exemple de compression et décompression

Path rawFile = Paths.get("raw.txt");
Path compressedFile = Paths.get("compressed.lzma");

LzmaCompressor lzmaCompressor = new LzmaCompressor(rawFile, compressedFile);
lzmaCompressor.compress();
lzmaCompressor.decompress();
2
BullyWiiPlaza

Voici des exemples testés d'utilisation de XZ Utils , une bibliothèque Java pure pour compresser et décompresser des archives XZ avec l'algorithme de compression LZMA2 avec un excellent rapport qualité-prix.

import org.tukaani.xz.*;

// CompressXz
public static void main(String[] args) throws Exception {
    String from = args[0];
    String to = args[1];
    try (FileOutputStream fileStream = new FileOutputStream(to);
         XZOutputStream xzStream = new XZOutputStream(
                 fileStream, new LZMA2Options(LZMA2Options.PRESET_MAX), BasicArrayCache.getInstance())) {

        Files.copy(Paths.get(from), xzStream);
    }
}

// DecompressXz
public static void main(String[] args) throws Exception {
    String from = args[0];
    String to = args[1];
    try (FileInputStream fileStream = new FileInputStream(from);
         XZInputStream xzStream = new XZInputStream(fileStream, BasicArrayCache.getInstance())) {

        Files.copy(xzStream, Paths.get(to), StandardCopyOption.REPLACE_EXISTING);
    }
}

// DecompressXzSeekable (partial)
public static void main(String[] args) throws Exception {
    String from = args[0];
    String to = args[1];
    int offset = Integer.parseInt(args[2]);
    int size = Integer.parseInt(args[3]);
    try (SeekableInputStream fileStream = new SeekableFileInputStream(from);
         SeekableXZInputStream xzStream = new SeekableXZInputStream(fileStream, BasicArrayCache.getInstance())) {

        xzStream.seek(offset);
        byte[] buf = new byte[size];
        if (size != xzStream.read(buf)) {
            xzStream.available(); // let it throw the last exception, if any
            throw new IOException("Truncated stream");
        }
        Files.write(Paths.get(to), buf);
    }
}
0
Vadzim