Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/401.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/apache/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用apache common compress/org.tukaani.xz在java中解码LZMA压缩zip文件时出现问题_Java_Apache_Lzma_Compression - Fatal编程技术网

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

使用apache common compress/org.tukaani.xz在java中解码LZMA压缩zip文件时出现问题,java,apache,lzma,compression,Java,Apache,Lzma,Compression,获取org.tukaani.xz.UnsupportedOptionsException:尝试解码LZMA compress xls文件时,未压缩大小太大错误。而非LZMA文件的解包/解码没有任何问题。两种情况下,压缩的xls文件相同 我正在使用ApacheCommonsCompress和org.tukaani.xz 参考样本代码 package com.concept.utilities.zip; import java.io.File; import java.io.IOException

获取org.tukaani.xz.UnsupportedOptionsException:尝试解码LZMA compress xls文件时,未压缩大小太大错误。而非LZMA文件的解包/解码没有任何问题。两种情况下,压缩的xls文件相同

我正在使用ApacheCommonsCompress和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();
        }

    }

}
错误

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)
org.tukaani.xz.UnsupportedOptionsException:未压缩的大小太大
位于org.tukaani.xz.LZMAInputStream.initialize(未知源)
位于org.tukaani.xz.LZMAInputStream。(未知来源)
位于org.apache.commons.compress.compressors.lzma.LZMACompressorInputStream.(LZMACompressorInputStream.java:50)
位于com.concept.utilities.zip.ApacheComm.extractLZMAZip(ApacheComm.java:209)
位于com.concept.utilities.zip.ApacheComm.main(ApacheComm.java:224)

我错过什么了吗?有没有其他方法可以用compression method=LZMA解码zip文件

您的代码不起作用的原因是,zip LZMA压缩的数据段与普通压缩的LZMA文件具有不同的头

您可以阅读(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属性标题中属性信息的存储字段如下所示:

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版本中的WriteCodeProperties()获取

代码示例:

import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
导入org.apache.commons.compress.archivers.zip.ZipFile;
导入org.apache.commons.compress.archivers.zip.ZipMethod;
导入org.apache.commons.io.IOUtils;
导入org.tukaani.xz.LZMAInputStream;
导入java.io.IOException;
导入java.io.InputStream;
导入java.nio.ByteBuffer;
导入java.nio.ByteOrder;
公共类ApacheComm
{
公共InputStream getInputstreamForEntry(ZipFile ZipFile,ZipArchiveEntry ze)引发IOException
{
if(zipFile.canReadEntryData(ze))
{
返回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版本
int majorVersion=buffer.get();
int minorVersion=buffer.get();
//以下数据的字节计数表示为无符号短字符。
//在所有版本中应为=5(propByte+dictSize)
int size=buffer.getShort()&0xffff;
如果(尺寸!=5)
抛出新的UnsupportedOperationException();
byte propByte=buffer.get();
//字典大小是一个无符号的32位小尾数整数。
int dictSize=buffer.getInt();
长时间未压缩;

如果((ze.getRawFlag()&(1)您试图解码的文件有多大?为了进行测试,我使用的是小型xls文件。有两列三行,包括头.26KB。zip文件本身有多大?3KB。zip文件包含在一个xls上。非常感谢这段代码!我得到了一个
不支持的DzipFeatureException
异常,只有基本的
BufferedInputStream
和Apache Common的Compress(解码用Win 10的压缩器创建的zip,显然其中的随机文件使用LZMA,而大多数不使用)。使用他们的“LZMA”只是抛出了op的例外:
未压缩的大小太大
但是现在一切都正常了!:)