• java操作jar文件


    前言

    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文件

  • 相关阅读:
    如何快速生成数据文件(fsutil命令,使用CreateFile和SetEndOfFile API函数,fopen和fseek RTL函数)
    TestDisk 数据恢复 重建分区表恢复文件-恢复diskpart clean
    利用winIO3.0进行windows10 64bit端口读取
    一个字体,大小,颜色可定义的自绘静态框控件-XColorStatic 类(比较好看,一共19篇自绘文章)
    美国富人与穷人的四个决定性差别!(冒风险、交朋友、敬业、生活习惯好)
    WebRTC 音视频开发
    协程的理解
    线程、进程、协程和队列
    Confluent
    “Options模式”下各种类型的Options对象是如何绑定的?
  • 原文地址:https://www.cnblogs.com/strongmore/p/14203458.html
Copyright © 2020-2023  润新知