Java解压文件的一些坑及经验分享(MALFORMED异常)
一、错误如下:
java.lang.IllegalArgumentException: MALFORMED at java.util.zip.ZipCoder.toString(ZipCoder.java:58) at java.util.zip.ZipInputStream.readLOC(ZipInputStream.java:300) at java.util.zip.ZipInputStream.getNextEntry(ZipInputStream.java:122) at com.huawei.vcm.verification.platform.util.ZipUtil.checkOriginalFile(ZipUtil.java:621) at com.huawei.vcm.verification.platform.ZipTest.main(ZipTest.java:8)
二、原因描述
由于操作系统平台的差异,导致zip压缩包的编码格式不同,windows默认使用GB2312格式,mac和linux默认使用utf-8格式,造成这种现象的原因有几种可能:
- 压缩包中包含中文
- 在linux上压缩,在windows上使用解压工具解压
- 使用jdk api直接解压
三、解决方案
基于上述问题,针对不同场景可以有不同的解决方式,我的是因为压缩包中有中文,造成解压异常,这个对于结果来说也是一种情况,故捕获异常,做处理即可。
catch (IllegalArgumentException e) { LOGGER.error("IllegalArgumentException:{}", e); }
其他两种解决解决方式:
- 将UTF-8改成GBK
ZipFile zipFile = new ZipFile(sourceFile, Charset.forName("GBK"));
– ZipCoder 58行异常位置
String toString(byte[] ba, int length) { CharsetDecoder cd = decoder().reset(); int len = (int)(length * cd.maxCharsPerByte()); char[] ca = new char[len]; if (len == 0) return new String(ca); // UTF-8 only for now. Other ArrayDeocder only handles // CodingErrorAction.REPLACE mode. ZipCoder uses // REPORT mode. if (isUTF8 && cd instanceof ArrayDecoder) { int clen = ((ArrayDecoder)cd).decode(ba, 0, length, ca); if (clen == -1) // malformed throw new IllegalArgumentException("MALFORMED"); return new String(ca, 0, clen); } ByteBuffer bb = ByteBuffer.wrap(ba, 0, length); CharBuffer cb = CharBuffer.wrap(ca); CoderResult cr = cd.decode(bb, cb, true); if (!cr.isUnderflow()) throw new IllegalArgumentException(cr.toString()); cr = cd.flush(cb); if (!cr.isUnderflow()) throw new IllegalArgumentException(cr.toString()); return new String(ca, 0, cb.position()); }
- 使用Apache commons-compress 工具包解决跨平台编码问题
下一篇:
DOM是什么?(超详细解释)