一、错误如下:
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 工具包解决跨平台编码问题