文章目录
- 一、引入依赖
- 二、文件准备
- 三、Java编码实现
- 四、Compress编码实现
一、引入依赖
<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.5</version></dependency><!-- slf4j + log4j2 begin --><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-slf4j-impl</artifactId><version>2.12.1</version></dependency><!-- log4j end --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.12</version><scope>provided</scope></dependency> <dependency><groupId>org.apache.commons</groupId><artifactId>commons-compress</artifactId><version>1.23.0</version><scope>test</scope></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency>
二、文件准备
三、Java编码实现
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.SystemUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.junit.Test;import lombok.extern.slf4j.Slf4j;/*** @author 00fly**/
@Slf4j
public class JarEntryTest
{/*** JDK-API实现-将addFiles添加到srcJar并重命名为newJar* * @param srcJar* @param newJar* @param addFiles* @throws IOException*/private void addFilesToJar(File srcJar, String newJar, File... addFiles)throws IOException{try (JarInputStream jis = new JarInputStream(new FileInputStream(srcJar)); JarOutputStream jos = new JarOutputStream(new FileOutputStream(newJar), jis.getManifest())){JarEntry jarEntry;while ((jarEntry = jis.getNextJarEntry()) != null){jos.putNextEntry(jarEntry);IOUtils.copy(jis, jos);}// 追加文件for (File addFile : addFiles){jarEntry = new JarEntry("add/" + addFile.getName());jos.putNextEntry(jarEntry);try (InputStream entryInputStream = new FileInputStream(addFile)){IOUtils.copy(entryInputStream, jos);}}}}/*** 拷贝 Jar* * @param fromJar* @param toJar* @throws IOException*/private void copyJar(String fromJar, String toJar)throws IOException{try (JarInputStream jis = new JarInputStream(new BufferedInputStream(new FileInputStream(fromJar))); JarOutputStream jos = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(toJar)), jis.getManifest())){JarEntry je;while ((je = jis.getNextJarEntry()) != null){jos.putNextEntry(je);int iRead;while ((iRead = jis.read()) != -1){jos.write(iRead);}}jis.closeEntry();jos.finish();}}@Testpublic void testAddFiles(){try{String src = getClass().getResource("/apache-jstl.jar").getPath();String add1 = getClass().getResource("/servlet-api.jar").getPath();String add2 = getClass().getResource("/log4j2.xml").getPath();String newJar = src.replace(".jar", DateFormatUtils.format(System.currentTimeMillis(), "_HHmmssSSS") + ".jar");log.info("源文件: {}", src);log.info("++新增: {}", add1);log.info("++新增: {}", add2);log.info("新文件: {}", newJar);addFilesToJar(new File(src), newJar, new File(add1), new File(add2));}catch (IOException e){log.error(e.getMessage(), e);}}@Testpublic void testCopy(){try{String src = getClass().getResource("/servlet-api.jar").getPath();String newJar = src.replace(".jar", DateFormatUtils.format(System.currentTimeMillis(), "_HHmmssSSS") + ".jar");log.info("源文件: {}", src);log.info("新文件: {}", newJar);copyJar(src, newJar);if (SystemUtils.IS_OS_WINDOWS){Runtime.getRuntime().exec("cmd /c start " + new File(newJar).getParentFile().getCanonicalPath());}}catch (IOException e){log.error(e.getMessage(), e);}}/*** 遍历打印* * @throws IOException*/@Testpublic void testList()throws IOException{String src = getClass().getResource("/servlet-api.jar").getPath();try (JarInputStream jis = new JarInputStream(new BufferedInputStream(new FileInputStream(src)))){JarEntry je;while ((je = jis.getNextJarEntry()) != null){System.out.println(je.getName());}jis.closeEntry();}}
}
四、Compress编码实现
Compress 功能非常强大,可以参考官网样例:
https://commons.apache.org/proper/commons-compress/examples.html
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;import org.apache.commons.compress.archivers.ArchiveOutputStream;
import org.apache.commons.compress.archivers.jar.JarArchiveEntry;
import org.apache.commons.compress.archivers.jar.JarArchiveInputStream;
import org.apache.commons.compress.archivers.jar.JarArchiveOutputStream;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.junit.Test;import lombok.extern.slf4j.Slf4j;@Slf4j
public class CompressTest
{@Testpublic void test()throws IOException{String src = getClass().getResource("/apache-jstl.jar").getPath();String add1 = getClass().getResource("/servlet-api.jar").getPath();String add2 = getClass().getResource("/log4j2.xml").getPath();String newJar = src.replace(".jar", DateFormatUtils.format(System.currentTimeMillis(), "_HHmmssSSS") + ".jar");log.info("源文件: {}", src);log.info("++新增: {}", add1);log.info("++新增: {}", add2);log.info("新文件: {}", newJar);try (JarArchiveInputStream jarInput = new JarArchiveInputStream(new FileInputStream(src)); ArchiveOutputStream outputStream = new JarArchiveOutputStream(new FileOutputStream(newJar))){JarArchiveEntry jarEntry;while ((jarEntry = jarInput.getNextJarEntry()) != null){outputStream.putArchiveEntry(jarEntry);IOUtils.copy(jarInput, outputStream);}outputStream.flush();// 追加addFilesString[] addFiles = {add1, add2};for (String addFile : addFiles){JarArchiveEntry addEntry = new JarArchiveEntry("add/" + StringUtils.substringAfterLast(addFile, "/"));outputStream.putArchiveEntry(addEntry);try (InputStream entryInputStream = new FileInputStream(addFile)){IOUtils.copy(entryInputStream, outputStream);}}// 追加add/001.txtJarArchiveEntry entry = new JarArchiveEntry("add/001.txt");outputStream.putArchiveEntry(entry);outputStream.write("org.apache.commons.compress.archivers.jar.JarArchiveOutputStream;".getBytes(StandardCharsets.UTF_8));outputStream.closeArchiveEntry();outputStream.finish();}}
}
有任何问题和建议,都可以向我提问讨论,大家一起进步,谢谢!
-over-