前言
JAR(Java Archive File),表示Java档案文件,是一种压缩文件,与常见的ZIP压缩文件兼容。区别在于JAR文件中默认包含一个名为META-INF/MANIFEST.MF的清单文件,这个文件是生成JAR文件时由系统自动创建的。我们可以将代码打包成jar,加入到classpath中,JVM会自动解压jar包。
创建jar包
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Objects;
import java.util.jar.Attributes;
import java.util.jar.Attributes.Name;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
public class Client {
public static void main(String[] args) {
compressFileToJar("D:/original_compute/testzip/test",
"D:/original_compute/testzip/test.jar",
"com.imooc.sourcecode.java.base.java5.autoboxing.test1.Client");
}
/**
* 读取文件内容并压缩
*
* @param filePath 文件路径
*/
private static void compressFileToJar(String filePath,
String jarFilePath, String mainClass) {
//创建清单文件,指定版本号和入口类
Manifest manifest = new Manifest();
Attributes attributes = manifest.getMainAttributes();
attributes.put(Name.MANIFEST_VERSION, "1.0");
attributes.put(Name.MAIN_CLASS, mainClass);
try (JarOutputStream jos = new JarOutputStream(new FileOutputStream(jarFilePath), manifest)) {
//递归的压缩文件夹和文件
doCompress("", filePath, jos);
//必须
jos.finish();
} catch (Exception e) {
e.printStackTrace();
}
}
private static void doCompress(String parentFilePath, String filePath, JarOutputStream jos) {
File sourceFile = new File(filePath);
if (!sourceFile.exists()) {
return;
}
String jarEntryName = parentFilePath + "/" + sourceFile.getName();
if (parentFilePath.isEmpty()) {
jarEntryName = sourceFile.getName();
}
if (sourceFile.isDirectory()) {
File[] childFiles = sourceFile.listFiles();
if (Objects.isNull(childFiles)) {
return;
}
for (File childFile : childFiles) {
doCompress(jarEntryName, childFile.getAbsolutePath(), jos);
}
} else {
int len = -1;
byte[] buf = new byte[1024];
jarEntryName = jarEntryName.substring(jarEntryName.indexOf("/") + 1);
try (InputStream input = new BufferedInputStream(new FileInputStream(sourceFile))) {
jos.putNextEntry(new JarEntry(jarEntryName));
while ((len = input.read(buf)) != -1) {
jos.write(buf, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
将一个目录下的所有文件打包成jar包
可以直接通过java命令运行
java -jar D:original_compute estzip est.jar
解压jar包
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarInputStream;
public class Client {
public static void main(String[] args) {
decompressFromJar("D:/original_compute/testzip/test.jar",
"D:/original_compute/testzip/");
}
/**
* 文件解压缩,支持文件和文件夹的解压
*
* @param jarFilePath 压缩包路径
* @param destFilePath 解压路径
*/
private static void decompressFromJar(String jarFilePath, String destFilePath) {
File file = new File(jarFilePath);
try (JarFile jarFile = new JarFile(file);
JarInputStream jis = new JarInputStream(new FileInputStream(file))) {
JarEntry jarEntry = null;
while ((jarEntry = jis.getNextJarEntry()) != null) {
String fileName = destFilePath + "/" + jarEntry.getName();
File entryFile = new File(fileName);
if (jarEntry.isDirectory()) {
//创建文件夹
entryFile.mkdir();
} else {
//创建文件之前必须保证父文件夹存在
if (!entryFile.getParentFile().exists()) {
entryFile.getParentFile().mkdirs();
}
//创建文件
entryFile.createNewFile();
}
try (InputStream input = jarFile.getInputStream(jarEntry);
OutputStream output = new FileOutputStream(entryFile)) {
int len = -1;
byte[] buf = new byte[1024];
while ((len = input.read(buf)) != -1) {
output.write(buf, 0, len);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
解压时会过滤掉清单文件
总结
JarInputStream和JarOutputStream都是ZipInputStream和ZipOutputStream的扩展类,不了解ZipInputStream的可以看 java操作zip文件