add zip method

This commit is contained in:
Looly
2020-01-11 19:09:02 +08:00
parent a203ffe191
commit 33c3d12cbb
3 changed files with 53 additions and 13 deletions

View File

@@ -17,12 +17,14 @@
* 【core 】 StrUtil增加contains方法issue#716@Github * 【core 】 StrUtil增加contains方法issue#716@Github
* 【core 】 QrCodeUtil增加背景透明支持pr#89@Gitee * 【core 】 QrCodeUtil增加背景透明支持pr#89@Gitee
* 【core 】 增加农历ChineseDatepr#90@Gitee * 【core 】 增加农历ChineseDatepr#90@Gitee
* 【core 】 ZipUtil增加zip方法写出到流issue#I17SCT@Gitee
### Bug修复 ### Bug修复
* 【core 】 修复NumberUtil.mul中null的结果错误问题issue#I17Y4J@Gitee * 【core 】 修复NumberUtil.mul中null的结果错误问题issue#I17Y4J@Gitee
* 【core 】 修复当金额大于等于1亿时转换会多出一个万字的bugpr#715@Github * 【core 】 修复当金额大于等于1亿时转换会多出一个万字的bugpr#715@Github
* 【core 】 修复FileUtil.listFileNames位于jar内导致的文件找不到问题 * 【core 】 修复FileUtil.listFileNames位于jar内导致的文件找不到问题
* 【core 】 修复TextSimilarity.similar去除字符导致的问题issue#I17K2A@Gitee * 【core 】 修复TextSimilarity.similar去除字符导致的问题issue#I17K2A@Gitee
* 【core 】 修复unzip文件路径问题issue#I17VU7@Gitee
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------

View File

@@ -172,14 +172,49 @@ public class ZipUtil {
* @param filter 文件过滤器,通过实现此接口,自定义要过滤的文件(过滤掉哪些文件或文件夹不加入压缩) * @param filter 文件过滤器,通过实现此接口,自定义要过滤的文件(过滤掉哪些文件或文件夹不加入压缩)
* @param srcFiles 要压缩的源文件或目录。如果压缩一个文件,则为该文件的全路径;如果压缩一个目录,则为该目录的顶层目录路径 * @param srcFiles 要压缩的源文件或目录。如果压缩一个文件,则为该文件的全路径;如果压缩一个目录,则为该目录的顶层目录路径
* @return 压缩文件 * @return 压缩文件
* @throws UtilException IO异常 * @throws IORuntimeException IO异常
* @since 4.6.5 * @since 4.6.5
*/ */
public static File zip(File zipFile, Charset charset, boolean withSrcDir, FileFilter filter, File... srcFiles) throws UtilException { public static File zip(File zipFile, Charset charset, boolean withSrcDir, FileFilter filter, File... srcFiles) throws IORuntimeException {
validateFiles(zipFile, srcFiles); validateFiles(zipFile, srcFiles);
try (ZipOutputStream out = getZipOutputStream(zipFile, charset)) { try (ZipOutputStream out = getZipOutputStream(zipFile, charset)) {
String srcRootDir; zip(out, charset, withSrcDir, filter, srcFiles);
} catch (IOException e) {
throw new IORuntimeException(e);
}
return zipFile;
}
/**
* 对文件或文件目录进行压缩
*
* @param out 生成的Zip到的目标流包括文件名。注意zipPath不能是srcPath路径下的子文件夹
* @param charset 编码
* @param withSrcDir 是否包含被打包目录只针对压缩目录有效。若为false则只压缩目录下的文件或目录为true则将本目录也压缩
* @param filter 文件过滤器,通过实现此接口,自定义要过滤的文件(过滤掉哪些文件或文件夹不加入压缩)
* @param srcFiles 要压缩的源文件或目录。如果压缩一个文件,则为该文件的全路径;如果压缩一个目录,则为该目录的顶层目录路径
* @throws IORuntimeException IO异常
* @since 5.1.1
*/
public static void zip(OutputStream out, Charset charset, boolean withSrcDir, FileFilter filter, File... srcFiles) throws IORuntimeException {
zip(getZipOutputStream(out, charset), withSrcDir, filter, srcFiles);
}
/**
* 对文件或文件目录进行压缩
*
* @param zipOutputStream 生成的Zip到的目标流不关闭此流
* @param withSrcDir 是否包含被打包目录只针对压缩目录有效。若为false则只压缩目录下的文件或目录为true则将本目录也压缩
* @param filter 文件过滤器,通过实现此接口,自定义要过滤的文件(过滤掉哪些文件或文件夹不加入压缩)
* @param srcFiles 要压缩的源文件或目录。如果压缩一个文件,则为该文件的全路径;如果压缩一个目录,则为该目录的顶层目录路径
* @throws IORuntimeException IO异常
* @since 5.1.1
*/
public static void zip(ZipOutputStream zipOutputStream, boolean withSrcDir, FileFilter filter, File... srcFiles) throws IORuntimeException {
String srcRootDir;
try{
for (File srcFile : srcFiles) { for (File srcFile : srcFiles) {
if (null == srcFile) { if (null == srcFile) {
continue; continue;
@@ -191,13 +226,12 @@ public class ZipUtil {
srcRootDir = srcFile.getCanonicalFile().getParentFile().getCanonicalPath(); srcRootDir = srcFile.getCanonicalFile().getParentFile().getCanonicalPath();
} }
// 调用递归压缩方法进行目录或文件压缩 // 调用递归压缩方法进行目录或文件压缩
zip(srcFile, srcRootDir, out, filter); zip(srcFile, srcRootDir, zipOutputStream, filter);
out.flush(); zipOutputStream.flush();
} }
} catch (IOException e) { } catch (IOException e) {
throw new UtilException(e); throw new IORuntimeException(e);
} }
return zipFile;
} }
/** /**
@@ -874,6 +908,9 @@ public class ZipUtil {
* @return {@link ZipOutputStream} * @return {@link ZipOutputStream}
*/ */
private static ZipOutputStream getZipOutputStream(OutputStream out, Charset charset) { private static ZipOutputStream getZipOutputStream(OutputStream out, Charset charset) {
if(out instanceof ZipOutputStream) {
return (ZipOutputStream)out;
}
return new ZipOutputStream(out, ObjectUtil.defaultIfNull(charset, DEFAULT_CHARSET)); return new ZipOutputStream(out, ObjectUtil.defaultIfNull(charset, DEFAULT_CHARSET));
} }
@@ -1080,15 +1117,16 @@ public class ZipUtil {
&& fileName.lastIndexOf(CharUtil.SLASH, fileName.length() - 2) > 0) { && fileName.lastIndexOf(CharUtil.SLASH, fileName.length() - 2) > 0) {
// 在Linux下多层目录创建存在问题/会被当成文件名的一部分,此处做处理 // 在Linux下多层目录创建存在问题/会被当成文件名的一部分,此处做处理
// 使用/拆分路径zip中无\),级联创建父目录 // 使用/拆分路径zip中无\),级联创建父目录
final String[] pathParts = StrUtil.splitToArray(fileName, CharUtil.SLASH); final List<String> pathParts = StrUtil.split(fileName, '/', false, true);
for (int i = 0; i < pathParts.length - 1; i++) { final int lastPartIndex = pathParts.size() - 1;//目录个数
for (int i = 0; i < lastPartIndex; i++) {
//由于路径拆分slip不检查在最后一步检查 //由于路径拆分slip不检查在最后一步检查
outFile = new File(outFile, pathParts[i]); outFile = new File(outFile, pathParts.get(i));
} }
//noinspection ResultOfMethodCallIgnored //noinspection ResultOfMethodCallIgnored
outFile.mkdirs(); outFile.mkdirs();
// 最后一个部分如果非空,作为文件名 // 最后一个部分如果非空,作为文件名
fileName = pathParts[pathParts.length - 1]; fileName = pathParts.get(lastPartIndex);
} }
return FileUtil.file(outFile, fileName); return FileUtil.file(outFile, fileName);
} }

View File

@@ -31,7 +31,7 @@ public class ZipUtilTest {
} }
@Test @Test
@Ignore // @Ignore
public void unzipTest2() { public void unzipTest2() {
File unzip = ZipUtil.unzip("f:/test/各种资源.zip", "f:/test/各种资源", CharsetUtil.CHARSET_GBK); File unzip = ZipUtil.unzip("f:/test/各种资源.zip", "f:/test/各种资源", CharsetUtil.CHARSET_GBK);
Console.log(unzip); Console.log(unzip);
@@ -40,7 +40,7 @@ public class ZipUtilTest {
@Test @Test
@Ignore @Ignore
public void unzipFromStreamTest() { public void unzipFromStreamTest() {
File unzip = ZipUtil.unzip(FileUtil.getInputStream("e:/test/antlr.zip"), FileUtil.file("e:/test/"), CharsetUtil.CHARSET_UTF_8); File unzip = ZipUtil.unzip(FileUtil.getInputStream("e:/test/hutool-core-5.1.0.jar"), FileUtil.file("e:/test/"), CharsetUtil.CHARSET_UTF_8);
Console.log(unzip); Console.log(unzip);
} }