Просмотр исходного кода

JarUtil增加重写zip条目的方法

JustryDeng 4 лет назад
Родитель
Сommit
481ca4648c

+ 61 - 3
class-winter-core/src/main/java/winter/com/ideaaedi/classwinter/util/JarUtil.java

@@ -17,6 +17,7 @@ import java.util.Collection;
 import java.util.Comparator;
 import java.util.Enumeration;
 import java.util.HashMap;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -87,7 +88,6 @@ public final class JarUtil {
                     zipEntry.setTime(file.lastModified());
                     zipEntry.setLastModifiedTime(FileTime.fromMillis(file.lastModified()));
                     zos.putNextEntry(zipEntry);
-                    zos.closeEntry();
                 }
                 // jar文件, 需要写CRC32信息
                 else if (fileName.endsWith(Constant.JAR_SUFFIX)) {
@@ -100,7 +100,6 @@ public final class JarUtil {
                     ze.setLastModifiedTime(FileTime.fromMillis(file.lastModified()));
                     zos.putNextEntry(ze);
                     zos.write(bytes);
-                    zos.closeEntry();
                 }
                 // 其它文件直接写入
                 else {
@@ -110,8 +109,8 @@ public final class JarUtil {
                     zos.putNextEntry(zipEntry);
                     byte[] bytes = IOUtil.toBytes(file);
                     zos.write(bytes);
-                    zos.closeEntry();
                 }
+                zos.closeEntry();
             }
         } catch (IOException e) {
             throw new ClassWinterException(e);
@@ -248,6 +247,65 @@ public final class JarUtil {
         return targetFile.getAbsolutePath();
     }
     
+    /**
+     * 修改zip文件(.java、.war文件)中的条目
+     *
+     * @param zipFile
+     *            要修改的zip文件(.java、.war文件)
+     * @param replacerMap
+     *            替换器(k-ZipFile中,要被替换的ZipEntry的相对路径,如:BOOT-INF/classes/application.yml; V-要替换成的内容)
+     * @return  被替换了的ZipEntry的相对路径及重写前后的内容信息<br/>
+     *          k - ZipEntry的相对路径,如:BOOT-INF/classes/application.yml<br/>
+     *          v - 左:重写前的内容,右:重写后的内容
+     */
+    public static Map<String, Pair<byte[], byte[]>> rewriteZipEntry(ZipFile zipFile, Map<String, byte[]> replacerMap) throws IOException {
+        Map<String, Pair<byte[], byte[]>> map = new HashMap<>(8);
+        if (replacerMap == null || replacerMap.size() == 0) {
+            return map;
+        }
+        if (zipFile == null) {
+            Logger.warn("zipFile is null.");
+            return map;
+        }
+        String zipFilePath = zipFile.getName();
+        if (!new File(zipFilePath).exists()) {
+            Logger.warn("zipFile [" + zipFilePath + "] non-exist.");
+            return map;
+        }
+        List<ZipEntry> zipEntryList = new LinkedList<>();
+        Enumeration<? extends ZipEntry> entries = zipFile.entries();
+        while (entries.hasMoreElements()) {
+            ZipEntry zipEntry = entries.nextElement();
+            zipEntryList.add(zipEntry);
+        }
+        // zipFile.getName()形如:   /abc/my-project.jar   /abc/my-project.war  /abc/my-projectzip
+        try (FileOutputStream fos = new FileOutputStream(zipFilePath, true);
+             ZipOutputStream zos = new ZipOutputStream(fos)) {
+            for (ZipEntry zipEntry : zipEntryList) {
+                final String zipEntryName = zipEntry.getName();
+                final byte[] originBytes = IOUtil.toBytes(zipFile.getInputStream(zipEntry));
+                final byte[] replaceBytes = replacerMap.get(zipEntryName);
+                if (replacerMap.containsKey(zipEntryName) && replaceBytes != null) {
+                    // 覆盖
+                    final ZipEntry ze = new ZipEntry(zipEntryName);
+                    ze.setMethod(ZipEntry.STORED);
+                    ze.setSize(replaceBytes.length);
+                    ze.setCrc(IOUtil.computeCrc32(replaceBytes));
+                    ze.setTime(zipEntry.getTime());
+                    ze.setLastModifiedTime(zipEntry.getLastModifiedTime());
+                    zos.putNextEntry(ze);
+                    zos.write(replaceBytes);
+                    map.put(zipEntryName, Pair.of(originBytes, replaceBytes));
+                } else {
+                    // 其它的不动
+                    zos.putNextEntry(new ZipEntry(zipEntry));
+                    zos.write(originBytes);
+                }
+            }
+        }
+        return map;
+    }
+    
     /**
      * 从(zip/jar/war)压缩文件中获取一个文件的字节
      * <p>