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
相关产品推荐
相关产品推荐

