赞
踩
在做zip文件解压缩的时候碰到一个异常信息,见下面的异常详情:
java.lang.IllegalArgumentException: MALFORMED[1]
at java.util.zip.ZipCoder.toString(ZipCoder.java:65) ~[na:1.8.0_181]
at java.util.zip.ZipFile.getZipEntry(ZipFile.java:583) ~[na:1.8.0_181]
at java.util.zip.ZipFile.access$900(ZipFile.java:60) ~[na:1.8.0_181]
at java.util.zip.ZipFile$ZipEntryIterator.next(ZipFile.java:539) ~[na:1.8.0_181]
at java.util.zip.ZipFile$ZipEntryIterator.nextElement(ZipFile.java:514) ~[na:1.8.0_181]
at java.util.zip.ZipFile$ZipEntryIterator.nextElement(ZipFile.java:495) ~[na:1.8.0_181]
代码:
- <!-- ZIP操作 -->
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-compress</artifactId>
- <version>1.16.1</version>
- </dependency>
ZipFile zipFile = new ZipFile(new File(filePath));
这种网上查下,很快定位问题,就是编码问题
然后各种查获取zip文件的编码,最多的就是cpdetector工具
https://blog.csdn.net/u014052432/article/details/79243496
pom:
- <dependency>
- <groupId>cpdetector</groupId>
- <artifactId>cpdetector</artifactId>
- <version>1.0.10</version>
- </dependency>
如果下不了的自行网上下载jar到对应的本地目录内,现在网上还真不好找这个jar,我是github内找到的
代码都编写好了,进行测试,确实能获取zip文件的编码,但是异常现象依旧存在。
然后又是各种 “zip获取编码”的查找,终于发现一篇:
guying4875大神写的博客:https://blog.csdn.net/guying4875/article/details/81034022
拷贝代码测试,顺利通过
- /**
- *
- */
-
- import java.io.BufferedInputStream;
- import java.io.BufferedReader;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.InputStreamReader;
- import java.io.OutputStreamWriter;
- import java.io.Writer;
- import java.util.BitSet;
-
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
-
- /**
- * @author 自动识别文件编码格式
- *
- */
- public class EncodeUtil {
- private static Logger logger = LoggerFactory.getLogger(EncodeUtil.class);
-
- private static int BYTE_SIZE = 8;
- public static String CODE_UTF8 = "UTF-8";
- public static String CODE_UTF8_BOM = "UTF-8_BOM";
- public static String CODE_GBK = "GBK";
-
- /**
- * 通过文件全名称获取编码集名称
- *
- * @param fullFileName
- * @param ignoreBom
- * @return
- * @throws Exception
- */
- public static String getEncode(String fullFileName, boolean ignoreBom) throws Exception {
- logger.debug("fullFileName ; {}", fullFileName);
- BufferedInputStream bis = new BufferedInputStream(new FileInputStream(fullFileName));
- return getEncode(bis, ignoreBom);
- }
-
- /**
- * 通过文件缓存流获取编码集名称,文件流必须为未曾
- *
- * @param bis
- * @param ignoreBom 是否忽略utf-8 bom
- * @return
- * @throws Exception
- */
- public static String getEncode(BufferedInputStream bis, boolean ignoreBom) throws Exception {
- bis.mark(0);
-
- String encodeType = "未识别";
- byte[] head = new byte[3];
- bis.read(head);
- if (head[0] == -1 && head[1] == -2) {
- encodeType = "UTF-16";
- } else if (head[0] == -2 && head[1] == -1) {
- encodeType = "Unicode";
- } else if (head[0] == -17 && head[1] == -69 && head[2] == -65) { //带BOM
- if (ignoreBom) {
- encodeType = CODE_UTF8;
- } else {
- encodeType = CODE_UTF8_BOM;
- }
- } else if ("Unicode".equals(encodeType)) {
- encodeType = "UTF-16";
- } else if (isUTF8(bis)) {
- encodeType = CODE_UTF8;
- } else {
- encodeType = CODE_GBK;
- }
- logger.info("result encode type : " + encodeType);
- return encodeType;
- }
-
- /**
- * 是否是无BOM的UTF8格式,不判断常规场景,只区分无BOM UTF8和GBK
- *
- * @param bis
- * @return
- */
- private static boolean isUTF8( BufferedInputStream bis) throws Exception {
- bis.reset();
-
- //读取第一个字节
- int code = bis.read();
- do {
- BitSet bitSet = convert2BitSet(code);
- //判断是否为单字节
- if (bitSet.get(0)) {//多字节时,再读取N个字节
- if (!checkMultiByte(bis, bitSet)) {//未检测通过,直接返回
- return false;
- }
- } else {
- //单字节时什么都不用做,再次读取字节
- }
- code = bis.read();
- } while (code != -1);
- return true;
- }
-
- /**
- * 检测多字节,判断是否为utf8,已经读取了一个字节
- *
- * @param bis
- * @param bitSet
- * @return
- */
- private static boolean checkMultiByte(BufferedInputStream bis, BitSet bitSet) throws Exception {
- int count = getCountOfSequential(bitSet);
- byte[] bytes = new byte[count - 1];//已经读取了一个字节,不能再读取
- bis.read(bytes);
- for (byte b : bytes) {
- if (!checkUtf8Byte(b)) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * 检测单字节,判断是否为utf8
- *
- * @param b
- * @return
- */
- private static boolean checkUtf8Byte(byte b) throws Exception {
- BitSet bitSet = convert2BitSet(b);
- return bitSet.get(0) && !bitSet.get(1);
- }
-
- /**
- * 检测bitSet中从开始有多少个连续的1
- *
- * @param bitSet
- * @return
- */
- private static int getCountOfSequential( BitSet bitSet) {
- int count = 0;
- for (int i = 0; i < BYTE_SIZE; i++) {
- if (bitSet.get(i)) {
- count++;
- } else {
- break;
- }
- }
- return count;
- }
-
-
- /**
- * 将整形转为BitSet
- *
- * @param code
- * @return
- */
- private static BitSet convert2BitSet(int code) {
- BitSet bitSet = new BitSet(BYTE_SIZE);
-
- for (int i = 0; i < BYTE_SIZE; i++) {
- int tmp3 = code >> (BYTE_SIZE - i - 1);
- int tmp2 = 0x1 & tmp3;
- if (tmp2 == 1) {
- bitSet.set(i);
- }
- }
- return bitSet;
- }
-
- /**
- * 将一指定编码的文件转换为另一编码的文件
- *
- * @param oldFullFileName
- * @param oldCharsetName
- * @param newFullFileName
- * @param newCharsetName
- */
- public static void convert(String oldFullFileName, String oldCharsetName, String newFullFileName, String newCharsetName) throws Exception {
- logger.info("the old file name is : {}, The oldCharsetName is : {}", oldFullFileName, oldCharsetName);
- logger.info("the new file name is : {}, The newCharsetName is : {}", newFullFileName, newCharsetName);
-
- StringBuffer content = new StringBuffer();
-
- BufferedReader bin = new BufferedReader(new InputStreamReader(new FileInputStream(oldFullFileName), oldCharsetName));
- String line;
- while ((line = bin.readLine()) != null) {
- content.append(line);
- content.append(System.getProperty("line.separator"));
- }
- newFullFileName = newFullFileName.replace("\\", "/");
- File dir = new File(newFullFileName.substring(0, newFullFileName.lastIndexOf("/")));
- if (!dir.exists()) {
- dir.mkdirs();
- }
- Writer out = new OutputStreamWriter(new FileOutputStream(newFullFileName), newCharsetName);
- out.write(content.toString());
- }
-
- }
修改后的代码:
- String fileEncode = EncodeUtil.getEncode(filePath,true);
- ZipFile zipFile = new ZipFile(new File(filePath), Charset.forName(fileEncode));
问题解决
再次感谢@guying4875
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。