You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python解压缩Java生成的Zip数据触发BadZipFile错误求助

问题:Java压缩Zip转Base64后Python解压缩失败

我用Java实现Zip压缩JSON数据并转Base64输出,再用Python解码后尝试读取Zip文件时,触发BadZipFile错误,提示“File is not a zip file”。

Java代码

String base64Str;
byte[] inBytes = "{\"a\":\"b\"}".getBytes(StandardCharsets.UTF_8);
try (
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ZipOutputStream zipOutputStream = new ZipOutputStream(out);
){
    zipOutputStream.putNextEntry(new ZipEntry("0"));
    zipOutputStream.write(inBytes);
    zipOutputStream.closeEntry();
    base64Str = Base64Encoder.encode(out.toByteArray());
    System.out.println(base64Str);
}catch (Exception e){
    return;
}

byte[] bytes = Base64Decoder.decode(base64Str);
try(
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ByteArrayInputStream in = new ByteArrayInputStream(bytes);
        ZipInputStream zin = new ZipInputStream(in);){
    zin.getNextEntry();
    byte[] buffer =  new byte[1024];
    int offset = -1;
    while ((offset = zin.read(buffer))!=-1){
        out.write(buffer,0,offset);
    }
    System.out.println(new String(buffer,StandardCharsets.UTF_8));

} catch (IOException e) {
    e.printStackTrace();
}

Python代码

import base64
import zipfile
import io

s = 'UEsDBBQACAgIAOl9VlYAAAAAAAAAAAAAAAABAAAAMKtWSlSyUkpSqgUAUEsHCJxc9msLAAAACQAAAA=='
bytes_data = base64.b64decode(s)
zipfile.ZipFile(io.BytesIO(bytes_data))

错误栈

---------------------------------------------------------------------------
BadZipFile                                Traceback (most recent call last)
Cell In[101], line 3
      1 s = 'UEsDBBQACAgIAOl9VlYAAAAAAAAAAAAAAAABAAAAMKtWSlSyUkpSqgUAUEsHCJxc9msLAAAACQAAAA=='
      2 bytes = base64.b64decode(s)
----> 3 zipfile.ZipFile(io.BytesIO(bytes))

File d:\python38\lib\zipfile.py:1269, in ZipFile.__init__(self, file, mode, compression, allowZip64, compresslevel, strict_timestamps)
   1267 try:
   1268     if mode == 'r':
-> 1269         self._RealGetContents()
   1270     elif mode in ('w', 'x'):
   1271         # set the modified flag so central directory gets written
   1272         # even if no files are added to the archive
   1273         self._didModify = True

File d:\python38\lib\zipfile.py:1336, in ZipFile._RealGetContents(self)
   1334     raise BadZipFile("File is not a zip file")
   1335 if not endrec:
-> 1336     raise BadZipFile("File is not a zip file")
   1337 if self.debug > 1:
   1338     print(endrec)

BadZipFile: File is not a zip file

问题原因及修复方案

问题根源

Java代码中未调用zipOutputStream.finish()或zipOutputStream.close(),导致Zip归档的中央目录(Central Directory)未被写入。Python的zipfile.ZipFile依赖中央目录识别Zip文件,而Java的ZipInputStream可通过逐个读取条目解析,无需完整中央目录,因此Java侧能正常读取,但Python侧报错。

另外原Java代码最后打印new String(buffer,StandardCharsets.UTF_8)存在错误,应该用out.toByteArray(),否则会输出buffer中未被覆盖的空字节。

修复后的Java代码

String base64Str;
byte[] inBytes = "{\"a\":\"b\"}".getBytes(StandardCharsets.UTF_8);
try (
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ZipOutputStream zipOutputStream = new ZipOutputStream(out);
){
    zipOutputStream.putNextEntry(new ZipEntry("0"));
    zipOutputStream.write(inBytes);
    zipOutputStream.closeEntry();
    zipOutputStream.finish(); // 关键:写入Zip中央目录
    base64Str = Base64.getEncoder().encodeToString(out.toByteArray());
    System.out.println(base64Str);
}catch (Exception e){
    e.printStackTrace();
    return;
}

byte[] bytes = Base64.getDecoder().decode(base64Str);
try(
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ByteArrayInputStream in = new ByteArrayInputStream(bytes);
        ZipInputStream zin = new ZipInputStream(in);){
    zin.getNextEntry();
    byte[] buffer =  new byte[1024];
    int offset = -1;
    while ((offset = zin.read(buffer))!=-1){
        out.write(buffer,0,offset);
    }
    System.out.println(new String(out.toByteArray(), StandardCharsets.UTF_8)); // 修复:使用out的字节数组而非原始buffer

} catch (IOException e) {
    e.printStackTrace();
}

修复后的Python测试

用修复后Java输出的Base64字符串替换s即可正常读取,示例代码:

import base64
import zipfile
import io

s = '修复后Java输出的Base64字符串'
bytes_data = base64.b64decode(s)
with zipfile.ZipFile(io.BytesIO(bytes_data)) as zf:
    with zf.open('0') as f:
        print(f.read().decode('utf-8'))

内容的提问来源于stack exchange,提问作者june

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 16:39:21