使用 apache common compress/org.tukaani.xz 在 java 中解码 LZMA 压缩 zip 文件时出现问题

2023-12-19

Getting org.tukaani.xz.UnsupportedOptionsException:未压缩的大小太大尝试解码 LZMA 压缩 xls 文件时出错。而非 LZMA 文件可以毫无问题地解压/解码。这两种情况都压缩相同的 xls 文件。

我正在使用 Apache commons compress 和 org.tukaani.xz。

示例代码供参考

package com.concept.utilities.zip;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;

import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.commons.compress.compressors.lzma.LZMACompressorInputStream;

public class ApacheComm {

    public void extractLZMAZip(File zipFile, String compressFileName, String destFolder) {

        ZipFile zip = null;
        try {

            zip = new ZipFile(zipFile);
            ZipArchiveEntry zipArchiveEntry = zip.getEntry(compressFileName);
            if (null != zipArchiveEntry) {
                String name = zipArchiveEntry.getName();

                // InputStream is = zip.getInputStream(zipArchiveEntry);
                InputStream israw = zip.getRawInputStream(zipArchiveEntry);

                LZMACompressorInputStream lzma = new LZMACompressorInputStream(israw);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != zip)
                ZipFile.closeQuietly(zip);
        }
    }

    public static void main(String[] args) throws IOException {

        ApacheComm c = new ApacheComm();
        try {
            c.extractLZMAZip(new File("H:\\archives\\rollLZMA.zip"), "roll.xls", "H:\\archives\\");
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}

Error

org.tukaani.xz.UnsupportedOptionsException: Uncompressed size is too big
    at org.tukaani.xz.LZMAInputStream.initialize(Unknown Source)
    at org.tukaani.xz.LZMAInputStream.<init>(Unknown Source)
    at org.apache.commons.compress.compressors.lzma.LZMACompressorInputStream.<init>(LZMACompressorInputStream.java:50)
    at com.concept.utilities.zip.ApacheComm.extractLZMAZip(ApacheComm.java:209)
    at com.concept.utilities.zip.ApacheComm.main(ApacheComm.java:224)

我错过了什么吗?还有其他方法可以解码吗压缩方法 = LZMA 的 zip 文件


您的代码不起作用的原因是 Zip LZMA 压缩数据段与普通压缩 LZMA 文件相比具有不同的标头。

您可以在以下位置阅读规格:https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT(4.4.4 通用位标志,5.8 LZMA - 方法 14),但引用重要部分:

5.8.5 [...] LZMA 压缩数据段将由 LZMA 属性标头和后跟 LZMA 压缩数据组成,如下所示:

[LZMA properties header for file 1]
[LZMA compressed data for file 1]

[...]

5.8.8 LZMA Properties Header 中属性信息的存储字段如下:

LZMA Version Information 2 bytes
LZMA Properties Size 2 bytes
LZMA Properties Data variable, defined by "LZMA Properties Size"

5.8.8.1 LZMA 版本信息 - 该字段标识用于压缩文件的 LZMA SDK 版本。第一个字节将存储 LZMA SDK 的主版本号,第二个字节将存储次版本号。

5.8.8.2 LZMA 属性大小 - 该字段定义剩余属性数据的大小。通常这个大小应该由 SDK 的版本决定。包含此大小字段是为了方便,并有助于避免将来由于此压缩算法的更改而出现任何歧义。

5.8.8.3 LZMA 属性数据 - 这个可变大小的字段记录 LZMA SDK 定义的解压缩器所需的值。存储在该字段中的数据应该使用“LZMA 版本信息”字段定义的 SDK 版本中的 WriteCoderProperties() 来获取。

代码示例:

import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.commons.compress.archivers.zip.ZipMethod;
import org.apache.commons.io.IOUtils;
import org.tukaani.xz.LZMAInputStream;

import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

public class ApacheComm
{
    public InputStream getInputstreamForEntry(ZipFile zipFile, ZipArchiveEntry ze) throws IOException
    {
        if (zipFile.canReadEntryData(ze))
        {
            return zipFile.getInputStream(ze);
        } else if (ze.getMethod() == ZipMethod.LZMA.getCode()) {
            InputStream inputStream = zipFile.getRawInputStream(ze);
            ByteBuffer buffer = ByteBuffer.wrap(IOUtils.readFully(inputStream, 9))
                    .order(ByteOrder.LITTLE_ENDIAN);

            // Lzma sdk version used to compress this data
            int majorVersion = buffer.get();
            int minorVersion = buffer.get();

            // Byte count of the following data represent as an unsigned short.
            // Should be = 5 (propByte + dictSize) in all versions
            int size = buffer.getShort() & 0xffff;
            if (size != 5)
                throw new UnsupportedOperationException();

            byte propByte = buffer.get();

            // Dictionary size is an unsigned 32-bit little endian integer.
            int dictSize = buffer.getInt();

            long uncompressedSize;
            if ((ze.getRawFlag() & (1 << 1)) != 0)
            {
                // If the entry uses EOS marker, use -1 to indicate
                uncompressedSize = -1;
            } else {
                uncompressedSize = ze.getSize();
            }

            return new LZMAInputStream(inputStream, uncompressedSize, propByte, dictSize);
        } else {
            throw new UnsupportedOperationException();
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 apache common compress/org.tukaani.xz 在 java 中解码 LZMA 压缩 zip 文件时出现问题 的相关文章

  • 如何让 BlazeDS 忽略属性?

    我有一个 java 类 它有一个带有 getter 和 setter 的字段 以及第二对 getter 和 setter 它们以另一种方式访问 该字段 public class NullAbleId private static final
  • 日期语句之间的 JPQL SELECT [关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我想将此 SQL 语句转换为等效的 JPQL SELECT FROM events WHERE events date BETWE
  • Java 枚举与创建位掩码和检查权限的混淆

    我想将此 c 权限模块移植到 java 但是当我无法将数值保存在数据库中然后将其转换为枚举表示形式时 我很困惑如何执行此操作 在 C 中 我创建一个如下所示的枚举 public enum ArticlePermission CanRead
  • 使用 LinkedList 实现下一个和上一个按钮

    这可能是一个愚蠢的问题 但我很难思考清楚 我编写了一个使用 LinkedList 来移动加载的 MIDI 乐器的方法 我想制作一个下一个和一个上一个按钮 以便每次单击该按钮时都会遍历 LinkedList 如果我硬编码itr next or
  • .properties 中的通配符

    是否存在任何方法 我可以将通配符添加到属性文件中 并且具有所有含义 例如a b c d lalalala 或为所有以结尾的内容设置一个正则表达式a b c anything 普通的 Java 属性文件无法处理这个问题 不 请记住 它实际上是
  • 为 java 游戏创建交互式 GUI

    大家好 我正在创建一个类似于 java 中的 farmville 的游戏 我只是想知道如何实现用户通常单击以与游戏客户端交互的交互式对象 按钮 我不想使用 swing 库 通用 Windows 看起来像对象 我想为我的按钮导入自定义图像 并
  • 如何更改javaFX中按钮的图像?

    我正在使用javaFX 我制作了一个按钮并为此设置了图像 代码是 Image playI new Image file c Users Farhad Desktop icons play2 jpg ImageView iv1 new Ima
  • 在 junit 测试中获取 javax.lang.model.element.Element 类

    我想测试我的实用程序类 ElementUtils 但我不知道如何将类作为元素获取 在 AnnotationProcessors 中 我使用以下代码获取元素 Set
  • 内部类的构造函数引用在运行时失败并出现VerifyError

    我正在使用 lambda 为内部类构造函数创建供应商ctx gt new SpectatorSwitcher ctx IntelliJ建议我将其更改为SpectatorSwitcher new反而 SpectatorSwitcher 是我正
  • 在 apache docker 容器中运行虚拟主机

    我在同一个 apache 容器中有两个 php 应用程序 我试图在端口上运行其中一个应用程序 因为它需要通过根域而不是子文件夹进行访问 我想在端口 8060 上运行应用程序 我尝试使用 apache 虚拟主机执行此操作 但它不会加载页面 h
  • 如何在谷歌地图android上显示多个标记

    我想在谷歌地图android上显示带有多个标记的位置 问题是当我运行我的应用程序时 它只显示一个位置 标记 这是我的代码 public class koordinatTask extends AsyncTask
  • java.io.Serialized 在 C/C++ 中的等价物是什么?

    C C 的等价物是什么java io Serialized https docs oracle com javase 7 docs api java io Serializable html 有对序列化库的引用 用 C 序列化数据结构 ht
  • 如何使用 jUnit 将测试用例添加到套件中?

    我有 2 个测试类 都扩展了TestCase 每个类都包含一堆针对我的程序运行的单独测试 如何将这两个类 以及它们拥有的所有测试 作为同一套件的一部分执行 我正在使用 jUnit 4 8 在 jUnit4 中你有这样的东西 RunWith
  • 干净构建 Java 命令行

    我正在使用命令行编译使用 eclipse 编写的项目 如下所示 javac file java 然后运行 java file args here 我将如何运行干净的构建或编译 每当我重新编译时 除非删除所有内容 否则更改不会受到影响 cla
  • 部署在 Apache2 系统上的 Dash 应用程序永远不会让用户通过“正在加载...”,因为它似乎无法找到其 dash .js 文件

    我正在尝试提供 python3 8 2 dash使用 Apache2 服务器的应用程序和mod wsgi 但应用程序停止在 正在加载 屏幕上 服务器为 dash 的每个 js 脚本返回 404 我在使用 dash 的内置本地服务器时没有遇到
  • 包 javax.el 不存在

    我正在使用 jre6 eclipse 并导入 javax el 错误 包 javax el 不存在 javac 导入 javax el 过来 这不应该是java的一部分吗 谁能告诉我为什么会这样 谢谢 米 EL 统一表达语言 是 Java
  • 在java中为组合框分配键

    我想添加一个JComboBox在 Swing 中这很简单 但我想为组合中的每个项目分配值 我有以下代码 JComboBox jc1 new JComboBox jc1 addItem a jc1 addItem b jc1 addItem
  • 如何将双精度/浮点四舍五入为二进制精度?

    我正在编写对浮点数执行计算的代码的测试 不出所料 结果很少是准确的 我想在计算结果和预期结果之间设置一个容差 我已经证实 在实践中 使用双精度 在对最后两位有效小数进行四舍五入后 结果始终是正确的 但是usually四舍五入最后一位小数后
  • 使用 svn 1.8.x、subclise 1.10 的 m2e-subclipse 连接器在哪里?

    我读到 m2e 的生产商已经停止生产 svn 1 7 以外的任何版本的 m2e 连接器 Tigris 显然已经填补了维护 m2e subclipse 连接器的空缺 Q1 我的问题是 使用 svn 1 8 x 的 eclipse 更新 url
  • 如何防止在Spring Boot单元测试中执行import.sql

    我的类路径中有一个 import sql 文件 其中包含一些 INSERT 语句 当使用 profile devel 运行我的应用程序时 它的数据被加载到 postgres 数据库中 到目前为止一切正常 当使用测试配置文件执行测试时 imp

随机推荐