Как использовать LZMA SDK для сжатия / распаковки в Java - PullRequest
16 голосов
/ 30 марта 2011

http://www.7 -zip.org / sdk.html Этот сайт предоставляет LZMA SDK для сжатия / распаковки файлов, я хотел бы попробовать его, но я потерян.

Кто-нибудь получил опыт в этом?Или учебник?Спасибо.

Ответы [ 6 ]

38 голосов
/ 08 февраля 2012

Краткий ответ: не

7zip sdk старый и не поддерживается, и это просто оболочка JNI вокруг библиотеки C ++. Чистая реализация Java на современной JVM (1.7+) такая же быстрая, как и реализация на C ++, и в ней меньше проблем с зависимостями и переносимостью.

Посмотрите на http://tukaani.org/xz/java.html

XZ - это формат файла, основанный на LZMA2 (улучшенная версия LZMA)

Ребята, которые изобрели формат XZ, строят чистую Java-реализацию алгоритмов сжатия / извлечения архива XZ

Формат файла XZ предназначен для хранения только 1 файла. Таким образом, вам нужно сначала сжать / сжать исходные папки в один несжатый файл.

Использовать библиотеку Java так же просто, как это:

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();
4 голосов
/ 30 марта 2011

Проверьте файлы LzmaAlone.java и LzmaBench.java в папке Java / SevenZip файла zip по той ссылке, которую вы опубликовали.

3 голосов
/ 28 сентября 2013

Используйте J7Zip.Это Java-порт LZMA SDK.Вы найдете его здесь:

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

альтернатива

Используйте lzmajio.jar с классами LzmaInputStream и LzmaOutputStream

вы найдете его на github:

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

2 голосов
/ 31 октября 2016

Вместо этого вы можете использовать эту библиотеку.Он «устарел», но все еще работает нормально.

Зависимость Maven

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

Класс полезности

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);
        }
    }
}

Сначала вы должны создать файл с содержимым, чтобы начать сжатие.Вы можете использовать этот веб-сайт для генерации произвольного текста.

Пример сжатия и распаковки

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

LzmaCompressor lzmaCompressor = new LzmaCompressor(rawFile, compressedFile);
lzmaCompressor.compress();
lzmaCompressor.decompress();
0 голосов
/ 14 июля 2019

https://mvnrepository.com/artifact/org.tukaani/xz/1.8

Код Котлина для Android:

 fun initDatabase() {
    var gisFile = this.getDatabasePath("china_gis.db");
    if (!gisFile.exists()) {
        if(!gisFile.parentFile.exists()) gisFile.parentFile.mkdirs();
        var inStream = assets.open("china_gis_no_poly.db.xz")
        inStream.use { input ->
            val buf = ByteArray(1024)
            XZInputStream(input).use { input ->
                FileOutputStream(gisFile,true).use { output ->
                    var size: Int
                    while (true) {
                        size = input.read(buf);
                        if (size != -1) {
                            output.write(buf, 0, size)
                        } else {
                            break;
                        }
                    }
                    output.flush()
                }

            }
        }
    }
}

Java-код:

 byte[] buf = new byte[8192];
    String name =  "C:\\Users\\temp22\\Downloads\\2017-007-13\\china_gis_no_poly.db.xz";
    try {

      InputStream input = new FileInputStream(name);
                FileOutputStream output=  new FileOutputStream(name+".db");
                try {
                    // Since XZInputStream does some buffering internally
                    // anyway, BufferedInputStream doesn't seem to be
                    // needed here to improve performance.
                    // in = new BufferedInputStream(in);
                    input = new XZInputStream(input);

                    int size;
                    while ((size = input.read(buf)) != -1)
                        output.write(buf, 0, size);
                    output.flush();

                } finally {
                    // Close FileInputStream (directly or indirectly
                    // via XZInputStream, it doesn't matter).
                    input.close();
                    output.close();
                }

    } catch (FileNotFoundException e) {
        System.err.println("XZDecDemo: Cannot open " + name + ": "
                           + e.getMessage());
        System.exit(1);

    } catch (EOFException e) {
        System.err.println("XZDecDemo: Unexpected end of input on "
                           + name);
        System.exit(1);

    } catch (IOException e) {
        System.err.println("XZDecDemo: Error decompressing from "
                           + name + ": " + e.getMessage());
        System.exit(1);
    }
0 голосов
/ 23 марта 2018

Вот проверенные примеры использования XZ Utils чистой библиотеки Java для упаковки и распаковки архивов XZ с алгоритмом сжатия LZMA2 с большим соотношением.

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);
    }
}
...