使用7z的Commons Compress使Stream不是BZip2格式

时间:2018-05-06 10:45:49

标签: java 7zip apache-commons-compress

我有这个受密码保护的7z档案,可以单独用7z正确打开和提取。但是使用下面的代码:

    byte[] PASSWORD = "secret".getBytes();
    String fileName = "r:/txt.7z";
    SevenZArchiveEntry entry;
    try (SevenZFile arch = new SevenZFile(new File(fileName), PASSWORD)) {
        while ((entry = arch.getNextEntry()) != null) {
            System.out.println(entry.getName());
        }
//      for (var e : arch.getEntries()) {
//          System.out.println(e.getName());
//      }
    }

导致此异常:

Exception in thread "main" java.io.IOException: Stream is not in the BZip2 format
  at org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream.init(BZip2CompressorInputStream.java:252)
  at org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream.<init>(BZip2CompressorInputStream.java:134)
  at org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream.<init>(BZip2CompressorInputStream.java:112)
  at org.apache.commons.compress.archivers.sevenz.Coders$BZIP2Decoder.decode(Coders.java:254)
  at org.apache.commons.compress.archivers.sevenz.Coders.addDecoder(Coders.java:79)
  at org.apache.commons.compress.archivers.sevenz.SevenZFile.buildDecoderStack(SevenZFile.java:933)
  at org.apache.commons.compress.archivers.sevenz.SevenZFile.buildDecodingStream(SevenZFile.java:909)
  at org.apache.commons.compress.archivers.sevenz.SevenZFile.getNextEntry(SevenZFile.java:222)

请注意,如果您取消注释for循环并注释掉while循环,它实际上会在归档中打印(唯一的)文件名。它是getNextEntry触发关于BZip2格式的异常。

我无法找到有关此问题的任何错误报告。当然我认为它可能是不正确的密码,所以我把它改成了一些垃圾,看看结果,但是它给出了不同的异常和消息中的建议,可能是密码不正确。所以,似乎密码肯定是正确的,但我无法解压缩文件。

我的类路径中也有xz-1.8.jar(org.tukaani.xz)。

我还尝试了使用SevenZFile的{​​{1}}构造函数,但会弹出完全相同的异常。

任何线索?

1 个答案:

答案 0 :(得分:1)

这个答案的功劳应该归功于Apache的Stefan Bodewig(请参阅https://issues.apache.org/jira/browse/COMPRESS-452我在哪里提交错误报告),但是我也把它放在这里以防任何人遇到同样的问题。事实证明,表示密码的字节数组应采用UTF16-LE编码,因此实际修复问题的是这个小片段:

byte[] PASSWORD = "secret".getBytes("UTF16-LE");

当然,人们必须照顾UnsupportedEncodingException。谢谢Stefan!