From eefb219e438177adf07714f8e7a5d3b964adacaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=AD=8F=E5=87=A1?= Date: Tue, 13 Jun 2023 15:36:18 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E4=B8=8D=E8=A7=A3=E5=8E=8Bzip=EF=BC=8C?= =?UTF-8?q?=E6=9B=BF=E6=8D=A2=E6=96=87=E4=BB=B6=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hutool/core/compress/ZipReplacer.java | 278 ++++++++++++++++++ 1 file changed, 278 insertions(+) create mode 100644 hutool-core/src/main/java/org/dromara/hutool/core/compress/ZipReplacer.java diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/compress/ZipReplacer.java b/hutool-core/src/main/java/org/dromara/hutool/core/compress/ZipReplacer.java new file mode 100644 index 000000000..2e72205b0 --- /dev/null +++ b/hutool-core/src/main/java/org/dromara/hutool/core/compress/ZipReplacer.java @@ -0,0 +1,278 @@ +package org.dromara.hutool.core.compress; + +import org.dromara.hutool.core.io.IORuntimeException; +import org.dromara.hutool.core.io.file.FileUtil; +import org.dromara.hutool.core.text.StrUtil; +import org.dromara.hutool.core.util.CharsetUtil; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.Charset; +import java.util.Arrays; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import java.util.regex.Matcher; +import java.util.stream.Collectors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipOutputStream; + +public class ZipReplacer { + + /** + * 不解压zip,替换文件内容,也可用于转换zip编码格式 + * + * @param srcFile 源文件 + * @param tarFile 输出文件 + * @param innerFiles 替换文件在zip中的相对路径 + * @param replaceFiles 替换文件到系统中到存储路径 + * @param charset 读取编码格式 + * @param charsetOut 输出编码格式 + */ + public static void replace(File srcFile, File tarFile, String[] innerFiles, File[] replaceFiles, Charset charset, Charset charsetOut) { +// 记录zip中是否存在相同路径的文件, 是 更新文件 否,添加文件 + boolean[] updates = new boolean[replaceFiles.length]; + try (ZipFile zipFile = new ZipFile(srcFile, charset); + FileOutputStream fos = new FileOutputStream(tarFile); + ZipOutputStream zos = new ZipOutputStream(fos); + ZipWriter zipWriter = new ZipWriter(zos, charsetOut)) { + HashMap data = new HashMap<>(); + for (Enumeration entries = zipFile.entries(); entries.hasMoreElements(); ) { + ZipEntry zipEntryIn = entries.nextElement(); + String zipEntryInName = zipEntryIn.getName(); +// false 未被替换 + boolean update = false; + for (int i = 0; i < innerFiles.length; i++) { + update = samePath(zipEntryInName, innerFiles[i]); +// 存在同路径文件,替换 + if (update) { + updates[i] = true; + data.put(zipEntryInName, FileUtil.getInputStream(replaceFiles[i])); + break; + } + } +// 不存在同路径文件,直接添加原zipEntry + if (!update) { + data.put(zipEntryInName, ZipUtil.getStream(zipFile, zipEntryIn)); + } + } +// 确认replaceFiles是否替换原zip中文件,没有替换直接添加 + for (int i = 0; i < updates.length; i++) { + if (!updates[i]) { +// 原zip中不存在同路径文件,添加到制定目录 + data.put(innerFiles[i], FileUtil.getInputStream(replaceFiles[i])); + } + } + for (String key : data.keySet()) { + zipWriter.add(key, data.get(key)); + } + } catch (IOException e) { + throw new IORuntimeException(e); + } + } + + public static void replace(File srcFile, File tarFile, String[] innerFiles, List replaceFiles, Charset charset, Charset charsetOut) { + File[] files = replaceFiles.toArray(new File[0]); + replace(srcFile, tarFile, innerFiles, files, charset, charsetOut); + } + + public static void replace(File srcFile, File tarFile, String[] innerFiles, String[] replaceFiles, Charset charset, Charset charsetOut) { + List files = Arrays.stream(replaceFiles).map(FileUtil::file).collect(Collectors.toList()); + replace(srcFile, tarFile, innerFiles, files, charset, charsetOut); + } + + /** + * 不解压zip,替换文件内容,也可用于转换zip编码格式 + * + * @param srcFile 源文件 + * @param tarFile 输出文件 + * @param innerFiles 替换文件在zip中的相对路径 + * @param replaceFiles 替换文件到系统中到存储路径 + * @param charset 读取输出编码格式 + */ + public static void replace(File srcFile, File tarFile, String[] innerFiles, String[] replaceFiles, Charset charset) { + replace(srcFile, tarFile, innerFiles, replaceFiles, charset, charset); + } + + public static void replace(File srcFile, File tarFile, String[] innerFiles, File[] replaceFiles, Charset charset) { + replace(srcFile, tarFile, innerFiles, replaceFiles, charset, charset); + } + + public static void replace(File srcFile, File tarFile, String[] innerFiles, List replaceFiles, Charset charset) { + replace(srcFile, tarFile, innerFiles, replaceFiles, charset, charset); + } + + /** + * 不解压zip,替换文件内容,也可用于转换zip编码格式 + * + * @param srcFile 源文件 + * @param tarFile 输出文件 + * @param innerFiles 要替换文件在zip中的相对路径 + * @param replaceFiles 替换文件到系统中到存储路径 + */ + public static void replace(File srcFile, File tarFile, String[] innerFiles, String[] replaceFiles) { + replace(srcFile, tarFile, innerFiles, replaceFiles, CharsetUtil.defaultCharset()); + } + + public static void replace(File srcFile, File tarFile, String[] innerFiles, File[] replaceFiles) { + replace(srcFile, tarFile, innerFiles, replaceFiles, CharsetUtil.defaultCharset()); + } + + public static void replace(File srcFile, File tarFile, String[] innerFiles, List replaceFiles) { + replace(srcFile, tarFile, innerFiles, replaceFiles, CharsetUtil.defaultCharset()); + } + + /** + * 不解压zip,替换文件内容,也可用于转换zip编码格式 + * + * @param srcFile 源文件,也是输出路径 + * @param innerFiles 替换文件在zip中的相对路径 + * @param replaceFiles 替换文件到系统中到存储路径 + * @param charset 读取输出编码格式 + */ + public static void replace(File srcFile, String[] innerFiles, String[] replaceFiles, Charset charset) { + replace(srcFile, srcFile, innerFiles, replaceFiles, charset); + } + + public static void replace(File srcFile, String[] innerFiles, File[] replaceFiles, Charset charset) { + replace(srcFile, srcFile, innerFiles, replaceFiles, charset); + } + + public static void replace(File srcFile, String[] innerFiles, List replaceFiles, Charset charset) { + replace(srcFile, srcFile, innerFiles, replaceFiles, charset); + } + + /** + * 不解压zip,替换文件内容,也可用于转换zip编码格式 + * + * @param srcFile 源文件 + * @param innerFiles 要替换文件在zip中的相对路径 + * @param replaceFiles 要替换的文件绝对路径 + */ + public static void replace(File srcFile, String[] innerFiles, String[] replaceFiles) { + replace(srcFile, srcFile, innerFiles, replaceFiles, CharsetUtil.defaultCharset()); + } + + public static void replace(File srcFile, String[] innerFiles, File[] replaceFiles) { + replace(srcFile, srcFile, innerFiles, replaceFiles, CharsetUtil.defaultCharset()); + } + + public static void replace(File srcFile, String[] innerFiles, List replaceFiles) { + replace(srcFile, srcFile, innerFiles, replaceFiles, CharsetUtil.defaultCharset()); + } + + /** + * 不解压zip,替换文件内容,也可用于转换zip编码格式 + * + * @param srcFilePath 源文件路径 + * @param tarFilePath 输出文件路径 + * @param innerFiles 要替换文件在zip中的相对路径 + * @param replaceFiles 要替换的文件绝对路径 + * @param charset 读取编码格式 + * @param charsetOut 输出编码格式 + */ + public static void replace(String srcFilePath, String tarFilePath, String[] innerFiles, String[] replaceFiles, Charset charset, Charset charsetOut) { + replace(FileUtil.file(srcFilePath), FileUtil.file(tarFilePath), innerFiles, replaceFiles, charset, charsetOut); + } + + public static void replace(String srcFilePath, String tarFilePath, String[] innerFiles, File[] replaceFiles, Charset charset, Charset charsetOut) { + replace(FileUtil.file(srcFilePath), FileUtil.file(tarFilePath), innerFiles, replaceFiles, charset, charsetOut); + } + + public static void replace(String srcFilePath, String tarFilePath, String[] innerFiles, List replaceFiles, Charset charset, Charset charsetOut) { + replace(FileUtil.file(srcFilePath), FileUtil.file(tarFilePath), innerFiles, replaceFiles, charset, charsetOut); + } + + /** + * 不解压zip,替换文件内容,也可用于转换zip编码格式 + * + * @param srcFilePath zip源文件路径 + * @param tarFilePath zip输出文件路径 + * @param innerFiles 要替换文件在zip中的相对路径 + * @param replaceFiles 要替换的文件绝对路径 + * @param charset 读取输出编码格式 + */ + public static void replace(String srcFilePath, String tarFilePath, String[] innerFiles, String[] replaceFiles, Charset charset) { + replace(FileUtil.file(srcFilePath), FileUtil.file(tarFilePath), innerFiles, replaceFiles, charset, charset); + } + + public static void replace(String srcFilePath, String tarFilePath, String[] innerFiles, File[] replaceFiles, Charset charset) { + replace(FileUtil.file(srcFilePath), FileUtil.file(tarFilePath), innerFiles, replaceFiles, charset, charset); + } + + public static void replace(String srcFilePath, String tarFilePath, String[] innerFiles, List replaceFiles, Charset charset) { + replace(FileUtil.file(srcFilePath), FileUtil.file(tarFilePath), innerFiles, replaceFiles, charset, charset); + } + + /** + * 不解压zip,替换文件内容,也可用于转换zip编码格式 + * + * @param srcFilePath 源文件路径 + * @param tarFilePath 输出文件路径 + * @param innerFiles 替换文件在zip中的相对路径 + * @param replaceFiles 替换文件到系统中到存储路径 + */ + public static void replace(String srcFilePath, String tarFilePath, String[] innerFiles, String[] replaceFiles) { + replace(FileUtil.file(srcFilePath), FileUtil.file(tarFilePath), innerFiles, replaceFiles, CharsetUtil.defaultCharset()); + } + + public static void replace(String srcFilePath, String tarFilePath, String[] innerFiles, File[] replaceFiles) { + replace(FileUtil.file(srcFilePath), FileUtil.file(tarFilePath), innerFiles, replaceFiles, CharsetUtil.defaultCharset()); + } + + public static void replace(String srcFilePath, String tarFilePath, String[] innerFiles, List replaceFiles) { + replace(FileUtil.file(srcFilePath), FileUtil.file(tarFilePath), innerFiles, replaceFiles, CharsetUtil.defaultCharset()); + } + + /** + * 不解压zip,替换文件内容,也可用于转换zip编码格式 + * + * @param srcFilePath 源文件路径,也是输出路径 + * @param innerFiles 要替换文件在zip中的相对路径 + * @param replaceFiles 要替换的文件绝对路径 + */ + public static void replace(String srcFilePath, String[] innerFiles, String[] replaceFiles) { + replace(FileUtil.file(srcFilePath), FileUtil.file(srcFilePath), innerFiles, replaceFiles, CharsetUtil.defaultCharset()); + } + + public static void replace(String srcFilePath, String[] innerFiles, File[] replaceFiles) { + replace(FileUtil.file(srcFilePath), FileUtil.file(srcFilePath), innerFiles, replaceFiles, CharsetUtil.defaultCharset()); + } + + public static void replace(String srcFilePath, String[] innerFiles, List replaceFiles) { + replace(FileUtil.file(srcFilePath), FileUtil.file(srcFilePath), innerFiles, replaceFiles, CharsetUtil.defaultCharset()); + } + + /** + * 判断路径是否相等 + * + * @param entryPath 路径A + * @param targetPath 路径B + * @param ignoreCase 是否忽略大小写 + * @return ture 路径相等 + */ + public static boolean samePath(String entryPath, String targetPath, boolean ignoreCase) { + + entryPath = entryPath.replaceAll("[/\\\\]", Matcher.quoteReplacement(File.separator)); + targetPath = targetPath.replaceAll("[/\\\\]", Matcher.quoteReplacement(File.separator)); + if (entryPath.startsWith(File.separator)) { + entryPath = entryPath.substring(1); + } + if (targetPath.startsWith(File.separator)) { + targetPath = targetPath.substring(1); + } + + if (ignoreCase) { + return StrUtil.equalsIgnoreCase(entryPath, targetPath); + } else { + return StrUtil.equals(entryPath, targetPath); + } + } + + public static boolean samePath(String entryPath, String targetPath) { + return samePath(entryPath, targetPath, true); + } +} From ff2930cba38e062ddc877852feb086eb70272d4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=AD=8F=E5=87=A1?= Date: Tue, 13 Jun 2023 15:44:40 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E7=94=A8List=E5=8F=82=E6=95=B0=E5=8E=BB?= =?UTF-8?q?=E8=B0=83=E7=94=A8array=E5=8F=82=E6=95=B0=E7=9A=84=E6=96=B9?= =?UTF-8?q?=E6=B3=95,=20=E8=BF=99=E4=B8=AA=E6=96=B9=E6=B3=95=E5=A4=8D?= =?UTF-8?q?=E7=94=A8=E9=80=BB=E8=BE=91=E6=98=AF=E4=B8=8D=E5=A4=AA=E5=A5=BD?= =?UTF-8?q?=E7=9A=84,=20List=E8=BD=ACarray=E4=BC=9A=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E6=96=B0=E6=95=B0=E7=BB=84,=20=E9=80=A0=E6=88=90=E6=80=A7?= =?UTF-8?q?=E8=83=BD=E6=B5=AA=E8=B4=B9.=20=E5=A6=82=E6=9E=9C=E5=8F=8D?= =?UTF-8?q?=E8=BF=87=E6=9D=A5,=20array=E8=BD=ACList,=20=E5=8F=AF=E4=BB=A5?= =?UTF-8?q?=E4=BD=BF=E7=94=A8Arrays.asList(),=20=E5=88=99=E5=8F=AF?= =?UTF-8?q?=E4=BB=A5=E5=87=8F=E5=B0=91=E5=AF=B9=E8=B1=A1=E5=88=9B=E5=BB=BA?= =?UTF-8?q?.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hutool/core/compress/ZipReplacer.java | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/compress/ZipReplacer.java b/hutool-core/src/main/java/org/dromara/hutool/core/compress/ZipReplacer.java index 2e72205b0..caefb758c 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/compress/ZipReplacer.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/compress/ZipReplacer.java @@ -32,9 +32,9 @@ public class ZipReplacer { * @param charset 读取编码格式 * @param charsetOut 输出编码格式 */ - public static void replace(File srcFile, File tarFile, String[] innerFiles, File[] replaceFiles, Charset charset, Charset charsetOut) { -// 记录zip中是否存在相同路径的文件, 是 更新文件 否,添加文件 - boolean[] updates = new boolean[replaceFiles.length]; + public static void replace(File srcFile, File tarFile, String[] innerFiles, List replaceFiles, Charset charset, Charset charsetOut) { + // 记录zip中是否存在相同路径的文件, 是 更新文件 否,添加文件 + boolean[] updates = new boolean[replaceFiles.size()]; try (ZipFile zipFile = new ZipFile(srcFile, charset); FileOutputStream fos = new FileOutputStream(tarFile); ZipOutputStream zos = new ZipOutputStream(fos); @@ -50,7 +50,7 @@ public class ZipReplacer { // 存在同路径文件,替换 if (update) { updates[i] = true; - data.put(zipEntryInName, FileUtil.getInputStream(replaceFiles[i])); + data.put(zipEntryInName, FileUtil.getInputStream(replaceFiles.get(i))); break; } } @@ -63,7 +63,7 @@ public class ZipReplacer { for (int i = 0; i < updates.length; i++) { if (!updates[i]) { // 原zip中不存在同路径文件,添加到制定目录 - data.put(innerFiles[i], FileUtil.getInputStream(replaceFiles[i])); + data.put(innerFiles[i], FileUtil.getInputStream(replaceFiles.get(i))); } } for (String key : data.keySet()) { @@ -73,10 +73,8 @@ public class ZipReplacer { throw new IORuntimeException(e); } } - - public static void replace(File srcFile, File tarFile, String[] innerFiles, List replaceFiles, Charset charset, Charset charsetOut) { - File[] files = replaceFiles.toArray(new File[0]); - replace(srcFile, tarFile, innerFiles, files, charset, charsetOut); + public static void replace(File srcFile, File tarFile, String[] innerFiles, File[] replaceFiles, Charset charset, Charset charsetOut) { + replace(srcFile, tarFile, innerFiles, Arrays.asList(replaceFiles), charset, charsetOut); } public static void replace(File srcFile, File tarFile, String[] innerFiles, String[] replaceFiles, Charset charset, Charset charsetOut) {