【问题标题】:decompressing with zlib in Java (incorrect header check)在 Java 中使用 zlib 解压缩(不正确的标头检查)
【发布时间】:2021-02-08 13:20:37
【问题描述】:

我尝试编程(并理解)压缩/解压缩。 我有一个用 zlib 压缩的文件,我认为我找到了解压缩文件的解决方案:

import java.util.Scanner;
import java.util.zip.*;
import java.io.*;

public class ZLibCompression
{
    public static void main(String args[])throws IOException, DataFormatException {
        File compressed = new File("./MyFile.hlb");
        
        decompress(compressed, new File("./MyFile.txt"));
        
    }
    
    public static void decompress(File compressed, File raw)
            throws IOException
    {
        try (InputStream inputStream = new InflaterInputStream(new FileInputStream(compressed));
             OutputStream outputStream = new FileOutputStream(raw))
        {
            copy(inputStream, outputStream);
        }
    }

 private static void copy(InputStream inputStream, OutputStream outputStream)
            throws IOException
    {
        byte[] buffer = new byte[1000];
        int length;

        while ((length = inputStream.read(buffer)) > 0)
        {
            outputStream.write(buffer, 0, length);
        }
    }
}

但我得到以下错误堆栈跟踪:

Exception in thread "main" java.util.zip.ZipException: incorrect header check
    at java.base/java.util.zip.InflaterInputStream.read(InflaterInputStream.java:164)
    at java.base/java.io.FilterInputStream.read(FilterInputStream.java:106)
    at ZLibCompression.copy(ZLibCompression.java:46)
    at ZLibCompression.decompress(ZLibCompression.java:20)
    at ZLibCompression.main(ZLibCompression.java:11)

然后我检查了文件的标题,它说:

{
 "compression" : {
  "crc32" : 2575274738,
  "decompressed_size" : 9020404,
  "type" : "zlib"
 },
 "encoded_data" : "eNrsvV2Xm0i

我的错误是什么?我发现一个 Python 脚本可以很好地处理同一个文件:

#!/usr/bin/env python
import sys
import os
import json
import base64
import zlib

SETLIST_OR_BUNDLE = "MyFile.hlb"

infile = open(SETLIST_OR_BUNDLE)
data = json.load(infile)
infile.close()

keys = list(data.keys())
if 'encoded_data' in keys:
    unz = zlib.decompress(base64.b64decode(data['encoded_data']))
    setlist_or_bundle = json.loads(unz)
    keys = list(setlist_or_bundle.keys())
    if 'setlists' in keys:
        setlists = setlist_or_bundle['setlists']
    elif 'presets' in keys:
        setlists = [setlist_or_bundle]
    for setlist in setlists:
        keys = list(setlist.keys())
        if 'meta' in keys:
            print()
            print("SETLIST: %s" % (setlist['meta']['name']))
        presets = setlist['presets']
        #print json.dumps(presets, indent=4)
        for preset in presets:
            if 'meta' in list(preset.keys()):
                meta = preset['meta']
                preset_name = meta['name']
                print("  ", preset_name)

我认为这与 base64 部分有关,我发现了一个类似的问题,其中有人提到“您必须先将 Base64 字符串解码为字节数组” - 好的 - 任何人都可以解释或给我一个链接教程? 我所需要的只是 Java 中的相同功能,就像上面的 Python 脚本一样 - 当然我想学习一些东西......

【问题讨论】:

  • Python zlib documentation 说:“zlib — 压缩与 gzip 兼容”。所以你应该尝试使用GZIPInputStream 而不是 InflaterInputStream。
  • 谢谢,我已更改为 GZIPInputStream,现在我收到错误“线程“主”java.util.zip.ZipException:不是 GZIP 格式中的异常”-我尝试使用解压缩文件winrar 并测试了 MyFile 的不同扩展名,如 .zip、.rar、.tz 等,但均未成功。所以我不知道那是什么压缩格式。唯一的提示是标头(“zlib”)和工作 Python 脚本(base64)。

标签: java zlib


【解决方案1】:

首先,您的文件似乎没有作为一个整体进行压缩。相反,它是一个 JSON 字符串,包含实际压缩数据为 encoded_data。然后,您还需要解开 JSON-String。处理 JSON 加密数据的最简单方法是使用库。查看this post 了解不同库的一些比较。

接下来,正如您在 python 代码中所见,编码数据在通过 ZLIB-Decompressor (zlib.decompress(base64.b64decode(data))) 之前从 Base64 解码

相当于 un-Base64 a String 的 java 是:

Base64.getDecoder().decode(string);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-21
    • 2015-05-29
    • 2015-09-25
    • 1970-01-01
    • 2013-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多