功能支持
- 支持标准zip输入流解析文件内容(无需依赖File)
- 支持读取网络url解析zip文件内容
- 支持本地zip文件路径解析文件内容
Maven依赖
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.4.3</version>
</dependency>
代码示例
package com.liuzhihong.practice.api.impl.utils;
import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import java.io.*;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
/**
* @author liuzhihong
* @date 2021-10-28
*/
@Slf4j
@SuppressWarnings("java:S1118")
public class CustomZipUtil {
/**
* 默认编码,使用平台相关编码
*/
private static final Charset DEFAULT_CHARSET = CharsetUtil.defaultCharset();
/**
* 根据zip文件url解析文件内容成map
*
* @param zipUrl 文件地址url
* @param filterFileSuffix 过滤zip里面指定后缀的文件
* @return map<key, value> key:文件全路径名 value:文件内容
*/
public static Map<String, String> unzipToMapByUrl(final String zipUrl, final List<String> filterFileSuffix) {
final InputStream inputStream = URLUtil.getStream(URLUtil.url(zipUrl));
return unzipByStream(inputStream, filterFileSuffix);
}
/**
* 根据zip文件路径解析文件内容成map
*
* @param path zip文件路径
* @param filterFileSuffix 过滤zip里面指定后缀的文件
* @return map<key, value> key:文件全路径名 value:文件内容
*/
public static Map<String, String> unzipToMapByPath(final String path, final List<String> filterFileSuffix) {
final BufferedInputStream inputStream = FileUtil.getInputStream(path);
return unzipByStream(inputStream, filterFileSuffix);
}
/**
* 根据zip文件解析文件内容成map
*
* @param zipFile zipFile
* @param filterFileSuffix 过滤zip里面指定后缀的文件
* @return map<key, value> key:文件全路径名 value:文件内容
*/
public static Map<String, String> unzipToMapByFile(final File zipFile, final List<String> filterFileSuffix) {
final BufferedInputStream inputStream = FileUtil.getInputStream(zipFile);
return unzipByStream(inputStream, filterFileSuffix);
}
/**
* 根据输入流解析解析文件内容成map
*
* @param inputStream zip文件输入流
* @param filterFileSuffix 过滤zip里面指定后缀的文件
* @return
* @throws UtilException
*/
public static Map<String, String> unzipByStream(final InputStream inputStream, List<String> filterFileSuffix) throws UtilException {
final Map<String, String> contentMap = Maps.newHashMap();
try (//转换成zip输入流
final ZipInputStream zipStream = new ZipInputStream(inputStream, DEFAULT_CHARSET);
final BufferedInputStream bufferedInputStream = new BufferedInputStream(zipStream)) {
ZipEntry zipEntry;
//循环读取压缩包里面的文件
while (null != (zipEntry = zipStream.getNextEntry())) {
if (!zipEntry.isDirectory()) {
parseFileContent(zipEntry, bufferedInputStream, contentMap, filterFileSuffix);
} else {
log.info("zipEntry is directory : {}", zipEntry.getName());
}
}
} catch (IOException e) {
throw new UtilException(e);
} finally {
IoUtil.close(inputStream);
}
return contentMap;
}
private static void parseFileContent(final ZipEntry zipEntry, final BufferedInputStream bufferedInputStream, final Map<String, String> contentMap,
final List<String> filterFileSuffix) throws IOException {
final StringBuilder content = new StringBuilder();
final String entryName = zipEntry.getName();
final int lastIndex = StrUtil.lastIndexOfIgnoreCase(entryName, ".");
//文件后缀
final String suffix = StringUtils.substring(entryName, lastIndex + 1);
if (!filterFileSuffix.contains(suffix)) {
final byte[] bytes = new byte[(int) zipEntry.getSize()];
bufferedInputStream.read(bytes, 0, (int) zipEntry.getSize());
//将文件转成流
try (final InputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(byteArrayInputStream))) {
//读取文件里面的内容
String line;
while ((line = bufferedReader.readLine()) != null) {
content.append(line);
}
contentMap.put(entryName, content.toString());
} catch (final Exception e) {
log.warn("parse inputStream filed.", e);
}
}
}
}