场景
使用ZipEntry解压zip文件报错: java.lang.IllegalArgumentException: MALFORMED
分析
压缩文件中含有中文, 在ZipCoder调用toString函数报错。此处识别成了utf8,
所以 在解压时设置成gbk字符集就行了
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);
if (isUTF8 && cd instanceof ArrayDecoder) {
int clen = ((ArrayDecoder)cd).decode(ba, 0, length, ca);
if (clen == -1)
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());
}
解决
ZipFile zf = new ZipFile(file, Charset.forName(“gbk”));
@Override
public void unZip(String srcPath, String dest) throws IOException {
File file = new File(srcPath);
if (!file.exists()) {
throw new RuntimeException(srcPath + "所指文件不存在");
}
ZipFile zf = new ZipFile(file, Charset.forName("gbk"));
Enumeration entries = zf.entries();
ZipEntry entry = null;
while (entries.hasMoreElements()) {
entry = (ZipEntry) entries.nextElement();
System.out.println("解压" + entry.getName());
if (entry.isDirectory()) {
String dirPath = dest + File.separator + entry.getName();
Path path = Paths.get(dirPath);
Files.createDirectories(path);
} else {
File f = new File(dest + File.separator + entry.getName());
if (!f.exists()) {
String dirs = f.getParent();
Path path = Paths.get(dirs);
Files.createDirectories(path);
}
f.createNewFile();
InputStream is = zf.getInputStream(entry);
FileOutputStream fos = new FileOutputStream(f);
int count;
byte[] buf = new byte[8192];
while ((count = is.read(buf)) != -1) {
fos.write(buf, 0, count);
}
is.close();
fos.close();
}
}
}
|