java操做jar文件

前言

JAR(Java Archive File),表示Java檔案文件,是一種壓縮文件,與常見的ZIP壓縮文件兼容。區別在於JAR文件中默認包含一個名爲META-INF/MANIFEST.MF的清單文件,這個文件是生成JAR文件時由系統自動建立的。咱們能夠將代碼打包成jar,加入到classpath中,JVM會自動解壓jar包。html

建立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命令運行spa

java -jar ‪D:\original_compute\testzip\test.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();
    }

  }
}

解壓時會過濾掉清單文件
code

總結

JarInputStream和JarOutputStream都是ZipInputStream和ZipOutputStream的擴展類,不瞭解ZipInputStream的能夠看 java操做zip文件htm

相關文章
相關標籤/搜索